《Kotlin 程序设计》第一章 Kotlin简介
第一章 Kotlin简介
正式上架:《Kotlin极简教程》Official on shelves: Kotlin Programming minimalist tutorial
京东JD:https://item.jd.com/12181725.html
天猫Tmall:https://detail.tmall.com/item.htm?id=558540170670
科特林岛(Котлин)是一座俄罗斯的岛屿,位于圣彼得堡以西约30公里处,形状狭长,东西长度约14公里,南北宽度约2公里,面积有16平方公里,扼守俄国进入芬兰湾的水道。科特林岛上建有喀琅施塔得市,为圣彼得堡下辖的城市。[7]
此开篇第一章也。
我们这里讲的Kotlin,就是一门以这个Котлин岛命名的现代程序设计语言。其主要设计者是来自 Saint Petersburg, Russia JetBrains团队的布雷斯拉夫,( Andrey Breslav , 更多信息可以参考:https://www.linkedin.com/in/abreslav/ ),源码实现主要是JetBrains团队以及开源贡献者。
1. Kotlin简介
首先来看看官网的介绍吧:
关键字是
静态类型编程语言
多平台:支持JVM平台,Android平台,浏览器JS,本地机器码等平台
与Java,Android 100%互通
认识一个事物的最好的方式,首先是取了解它的历史。
我们先来简单看一下来自wikipedia[0]的Kotlin简历:
标题 | 内容 |
---|---|
设计者 | JetBrains |
实现者 | JetBrains与开源贡献者 |
最新发行时间 | Kotlin 1.1.2(2017年4月25日,34天前) |
最新测试版发行日期 | Kotlin 1.1.3 EAP(2017年5月27日,2天前 [1]) |
类型系统 | 静态类型 |
系统平台 | 输出Java虚拟机比特码以及JavaScript源代码 |
操作系统 | 任何支持JVM或是JavaScript的解释器 |
许可证 | Apache 2 |
常用文件扩展名 | .kt |
网站 | kotlinlang.org |
启发语言 | Java、Scala、Groovy、C#、Gosu |
Kotlin是一种运行在Java虚拟机上静态类型编程语言,它也可以被编译成为JavaScript源代码。
另外,在没有JVM执行环境的平台上,比如 iOS, 嵌入式平台,我们可以使用Kotlin-Native(https://github.com/JetBrains/kotlin-native), 直接把Kotlin代码编译成本地机器码。
Kotlin 元年
2016 年是 Kotlin “元年(First year of Kotlin)”,官网给出了这样一幅图来展示它一年来的成绩:
image.pngGithub 上面的代码量都破千万了,使用 Kotlin 的公司也逐渐增多,除了 JetBrains 自己以外,我觉得在 Java 界比较有分量的就是 Square 了,如果 Google 能够稍微提一句 Kotlin ,显然这个故事就会有另外一个令人兴奋的版本——好啦,不要 yy 啦。
据说,比较著名的主要有Amazon Web Services, Pinterest, Coursera, Netflix, Uber, Square, Trello, Basecamp 这些公司将 Kotlin 投入了生产实践当中。国内资料较少,估计接触的人也不是很多,像百度、腾讯、阿里巴巴、滴滴、新美大、小米、京东这样的公司可能还没有太多的动力去将 Kotlin 应用到开发中,就算开始尝试,也多是在 Android 开发上面试水;而敢于尝试 Kotlin 的,更多是没有什么历史包袱且富于创新和挑战精神的创业团队,对于他们而言 Kotlin 为开发带来的效率是非常诱人的。
说到这里,有两个令人兴奋的消息需要同步给大家:
- Gradle 开始尝试用 Kotlin 作为其脚本语言,目前已经发到了 0.4.0。这个真的可以有,groovy 虽然是一门很灵活的语言,不过写配置的时候如果没有 IDE 的提示,实在是太痛苦了。大家有兴趣也可以关注一下这个项目:gradle-script-kotlin
- Spring 5.0 加入 Kotlin 支持,Spring 的地位可想而知,Spring 为 Kotlin 站台,这分量还是很重的。
在Google I/O 2017中,Google宣布在Android上为Kotlin提供一等支持。
Kotlin声称 100% interoperable with Java。Kotlin 能与 Java 混合使用,并且直接复用 Java 的生态系统(库、框架、工具)。一个已有的 Java 项目,只需引用 Kotlin 的 Maven/Gradle 插件,以及引用 Kotlin 标准库的依赖,就可以逐渐掺入 Kotlin 代码。你完全可以当它是 ** A Better Java ** 。
Kotlin 是由工程师设计,各种细节设计非常切合工程师的需要。语法近似 Java 和 Scala,且已活跃在 Android 开发领域,被誉为 Android 平台的 Swift。
其主要设计目标:
- 创建一种兼容 Java 的语言
- 让它比 Java 更安全,能够静态检测常见的陷阱。如:引用空指针
- 让它比 Java 更简洁,通过支持 variable type inference,higher-order functions (closures),extension functions,mixins and first-class delegation 等实现。
- 让它比最成熟的竞争对手 Scala语言更加简单。
Kotlin 的学习曲线极其平缓,学习量相当于一个框架。有经验的程序员阅读了文档即刻上手。
2. Kotlin基本特性
Kotlin 是一门支持多范式、多平台的编程语言。
Kotlin 支持面向对象、泛型与函数式等编程范式,它支持 JVM(Kotlin代码编译成JVM字节码)、Android、JavaScript (Kotlin代码编译转换成js代码)平台。而原生(Native)平台的 Kotlin 直接将源码编译为机器码,运行在没有JVM环境的平台。
Kotlin 具有很多下一代编程语言[6]静态语言特性:如类型推断、多范式支持、可空性表达、扩展函数、模式匹配等。
Kotlin的编译器kompiler(Kotlin的一系列以K字打头的用语——甚至连 contributors 这类词他们也用改成了kontributors)可以被独立出来并嵌入到 Maven、Ant 或 Gradle 工具链中。这使得在 IDE 中开发的代码能够利用已有的机制来构建,可以在新环境中自由使用。
Kotlin基本特性如下:
- 运行于JVM (Java Virtual Machine)上的语言,直接继承JVM生态所有成就。
- 静态类型,即变量类型是编译时确定的。
- 函数式的编程语言:
- 函数是一等公民: 函数既可以是变量,也可以当做参数传给另外一个函数。
- 不可变对象: 不可变对象的状态,运行时保持不变。
- 无副作用: 使用纯函数,不管执行多少次,针对相同输入,每次输出都一致。
- 支持面向对象编程(OOP,Object-Oriented Programming)。
- 完全开源。
Kotlin是静态类型的语言,也可以编程成Java字节码以及JavaScript,作为一个时髦又表现丰富的编程语言,Kotlin就是被设计用来生 产高性能要求的程序的,所以运行起来和Java也是不相上下。
Kotlin的定位非常有特点,它并不像是scala另起炉灶,将类库,尤其是集合类都自己来了一遍.
Kotlin是对现有Java的增强,通过扩展方法给java提供了很多诸如fp之类的特性,但同时始终保持对Java的兼容. 这是Kotlin官网首页重点强调的:
100% interoperable with Java™
这意味着什么呢?或者换个问法:我什么时候可以开始在我的项目中引入kotlin呢?
我的答案是: 现在,立刻,马上!
3. JVM语言家族简介
常见的JVM语言成员如下图所示:
JVM语言家族“我真正关心的是Java虚拟机的概念,因为是它把所有的东西都联系在了一起;是它造就了Java语言;是它使得事物能在所有的异构平台上得到运行;也还是它使得所有类型的语言能够共存。” ( James Gosling, Java之父 (2011, ServerSide))
一个完整的现代编程语言基本的组成有:词汇语法、编译器、语言规范、执行引擎、开发者API库等。
在JVM体系中,已经把后面四个打包提供出了一套完整的解决方案了( class文件协议,JVM ByteCode,JVM执行引擎,JDK等),而且在生产实践中得到广泛应用。
JVM,是用C/C++写的,跟操作系统打交道,目前看来这是最好的选择。JVM虚拟机,是所有基于JVM的编程语言与操作系统的中间层(实现跨平台)。
当我们基于JVM来设计一门新语言X,那么X语言编译器后端只需要输出 JVM 字节码就可以。我们知道,跨平台需要极大的工作量(这个轮子,造起来有点耗时耗力)。JVM 作为一个成熟的高层运行环境,为宿主语言提供了很多运行时所需要的服务,比如内存管理(垃圾回收器GC),很大程度上避免了额外的独立开发。
另外一个趋势是把 Javascript 成为新的目标平台。很多主流语言[2]都已经出现了编译器可以翻译成 Javascript,这也是得益于近年来 Javascript 虚拟机性能的显著提升。
另外,跟Kotlin可以称得上对手的JVM编程语言还有Groovy,Scala等。
Groovy
Groovy是一个动态类型的、面向对象的基于JVM的编程语言。它的语法风格与Java很像,但是把Java中一些繁杂的模板化编程代码重新封装提供出新的API了(比如说集合、文件、进程等模块)。
Java程序员能够很快的熟练使用 Groovy。另外,Groovy编译器是可以接受完全纯粹的Java语法格式的Groovy代码。这真是无缝集成了。
由于Groovy是一门动态类型语言,写代码的时候,我们可以像JavaScript一样“自由自在”。编译器能够推断出变量的类型。
同时Groovy也提供了字符串处理,xml的序列化与反序列化、JSON处理以及单元测试等功能模块。所有的这一切好处都能为程序员节约不少时间。
Scala
Scala是一门多范式的编程语言,混合了面向对象编程、函数式编程的各种特性。还有一套复杂的类型系统。
Scala提供了自己的一套并行编程框架。同时,自己实现了一套集合类。Scala代码能很好的被优化成字节码,运行起来和原生Java一样快。
Scala的语法风格跟Kotlin有几分神似。尽管Scala 更为强大些,Kotlin 还是尝试提供比 Java 更好的函数、模式匹配、空指针预防和泛型,以及特征(traits)和模式匹配。
** Xtend **
Xtend跟Kotlin 一样,旨在提供一种更好的 Java 而非重建整个新平台。这两种语言都向下编译为字节码( Xtend 是首先转换成相应的 Java 代码,再让 Java 编译器完成繁重的工作),而且两者都引入了函数和扩展函数(在某个有限范围内静态地增加一个新方法到某个已有类型的能力)。Xtend 是基于 Eclipse 的,而 Kotlin 是基于 IntelliJ 的,两者都提供无界面构建。
4. Kotlin 与 Scala
Kotlin要比 Scala简单。工程师通常会再加上一句:这取决于更简单的定义。
Scala使用一个相当复杂的类型系统,旨在为库设计师更大的自由度。
而Kotlin节制地控制了这个“自由”。比如以下是Scala的一些特性,Kotlin没有:
- 隐式参数和隐式转换 (Implicit parameters and implicit conversions)
- (路径)依赖类型 ( (Path-)dependent types)
- 全量存在的类型(Full-scale existential types)
- 支持查看边界,上下文边界和所有其他异常边界
- 宏(Macros)
等等[9]。
5. 为什么选择 Kotlin?
简洁
使用一行代码创建一个包含 getters、 setters、 equals()、 hashCode()、 toString() 以及 copy() 的 POJO:
data class Customer(val name: String, val email: String, val company: String)
或者使用 lambda 表达式来过滤列表:
val positiveNumbers = list.filter { it > 0 }
想要单例?创建一个 object 就可以了:
object ThisIsASingleton {
val companyName: String = "JetBrains"
}
这些特性跟Scala基本一样。
安全
彻底告别那些烦人的 NullPointerException:
var output: String
output = null // 编译错误
Kotlin 可以保护你避免对可空类型的误操作
val name: String? = null // 可空类型
println(name.length()) // 编译错误
这个带问号的可null类型,val name: String? = null
,应该是借鉴的C#。
如果你检查类型是正确的,编译器会为你做自动类型转换
fun calculateTotal(obj: Any) {
if (obj is Invoice)
obj.calculateTotal()
}
JVM 互操作性
Kotlin可以使用 JVM 上的任何现有库, 100% 兼容。
import io.reactivex.Flowable
import io.reactivex.schedulers.Schedulers
Flowable
.fromCallable {
Thread.sleep(1000) // 模仿高开销的计算
"Done"
}
.subscribeOn(Schedulers.io())
.observeOn(Schedulers.single())
.subscribe(::println, Throwable::printStackTrace)
无论是 JVM 还是 JavaScript 目标平台,都可用 Kotlin 来写代码。
import kotlin.browser.window
fun onLoad() {
window.document.body!!.innerHTML += "<br/>Hello, Kotlin!"
}
还有高性能的Kotlin Native,感觉Kotlin要逆天了!
工具化
一门语言需要工具化,而在 JetBrains,有Intelli IDEA!
Kotlin 1.1 新特性
1、更新要点
1.1 Coroutine
参考文章:
Kotlin 的 Coroutine 实现主要分为两个层面,
第一个层面就是标准库以及语言特性的支持,这里面主要包括最基本的 suspend 关键字以及诸如 startCoroutine 这样的方法扩展。
第二层面则主要是基于前面的基础封装的库,目前主要是 kotlinx.coroutine ,其中封装了 runBlock、launch 这样方便的操作 Coroutine 的 api。
我们再来简单说说 协程(Coroutine) 的运行机制。Coroutine 是用来解决并发问题的,它看上去跟线程似乎是并发问题的两种独立的解决方案,其实不然。
要并发的执行任务,从根本上说,就是要解决 Cpu 的调度问题,Cpu 究竟是如何调度,取决于操作系统,我们在应用程序编写的过程中用到的 Thread 也好,Coroutine 也好,本质上也是对操作系统并发 api 的封装。
知道了这一点,我们再来想想 Thread 是如何做到两个线程并发执行的呢?Java 虚拟机的实现主要采用了对内核线程映射的方式,换句话说,我们通常用到的 Thread 的真正直接调度者可以理解为是操作系统本身。那我们在 Kotlin 当中支持 Coroutine 是不是也要把每一个 Coroutine 映射到内核呢?显然不能,不然那跟 Thread 还有啥区别呢?再者,Coroutine 的核心在 Co 上,即各个 Coroutine 是协作运行的,有一种“你唱罢来我登场”的感觉,就是说,Coroutine 的调度权是要掌握在程序自己手中的。于是,如果你去了解 kotlinx.coroutine 的实现,你就会发现 CommonPool 这么个东西,它不是别的,它的背后正是线程池。
线程是轻量级进程,而协程则是轻量级线程。
Coroutine 的出现让 Kotlin 如虎添翼,如果你之前在写 Go,Lua,python,或者 C#,这回 Java 虚拟机家族可不会让你失望了。自从有了协程,你也可以写出这样的代码:
val fibonacci = buildSequence {
yield(1) // first Fibonacci number
var cur = 1
var next = 1
while (true) {
yield(next) // next Fibonacci number
val tmp = cur + next
cur = next
next = tmp
}
}
...
for (i in fibonacci){
println(i)
if(i > 100) break //大于100就停止循环
}
序列生成器,记得我刚学 python 那会儿看到这样的语法,简直惊呆了。
val imageA = loadImage(urlA)
val imageB = loadImage(urlB)
onImageGet(imageA, imageB)
这样的代码也是没有压力的,看上去就如同步代码一般,殊不知人家做的可是异步的事情呐。
协程的出现,让我们可以用看似同步的代码做着异步的事情。
这篇文章我们主要说说 1.1 的发版,Coroutine 的更多内容,建议大家直接点击前面的链接去读我的另外两篇文章~
1.2 JavaScript 支持
真是媳妇儿终于熬成婆,Js 终于被正式支持了。看官方的意思,他们已经用这一特性做了不少尝试,从 Kotlin 从头到尾写一个站点,似乎毫无压力,尽管类似反射这一的特性还没有支持,不过面包会有的嘛。
从我个人的角度来说,也可能我对前端了解太少吧,我觉得应用在前端比起移动端、服务端来说,Kotlin 的前景相对不明朗。我用 JavaScript 用得好好的,为啥要切换 Kotlin 呢?动态特性玩起来挺爽的,虽然回调写多了容易蛋疼,但这也不是不可以规避的。关于 Kotlin 开发前端这个问题,我需要多了解一下前端开发者的看法,相比他们是否愿意接触 Kotlin,我更关心有几个做前端的人知道这门语言。不瞒各位说,前几天跟一个支付宝客户端的大哥聊了一会儿,他问我这个 k o t 什么的,是干啥的。。。我当时在想,看来阿里人对 Kotlin 还不是很熟悉啊。
Whatever,Kotlin 现在都可以支持 node.js 了,还有什么不可能的呢?作为吃瓜群众,且让我观望一阵子。
1.3 中文支持
你放心,这一段内容你绝对在其他人那里看不到,因为没人会这么蛋疼。我前几天为了做一个案例用中文写了段代码,想着 Java 支持中文标识符,Kotlin 应该也问题不大。没曾想,写的时候一点儿问题的没,可编译的时候却直接狗带了。
package 中国.北京.回龙观
class G6出口{
fun 下高速(){
println("前方堵死, 请开启飞行模式 :)")
}
}
fun main(args: Array<String>) {
val 回龙观出口 = G6出口()
回龙观出口.下高速()
}
注意,包名、代码文件名都是中文的,如果用 1.0.6 版编译,结果就是万里江山一片红哇。
Error:Kotlin: [Internal Error] java.io.FileNotFoundException: /Users/benny/temp/testKotlin/out/production/testKotlin/??/??/???/G6??.class (No such file or directory)
at java.io.FileInputStream.open0(Native Method)
at java.io.FileInputStream.open(FileInputStream.java:195)
at java.io.FileInputStream.<init>(FileInputStream.java:138)
at kotlin.io.FilesKt__FileReadWriteKt.readBytes(FileReadWrite.kt:52)
at org.jetbrains.kotlin.incremental.LocalFileKotlinClass
...
注意到,汉字都变成了 ??,瞧瞧编译器那小眼神,真是看得我都醉了。
如果我们用 1.1 的编译器来编译这段代码,结果就可以正常输出:
前方堵死, 请开启飞行模式。
1.4 其他特性
1.1 还新增了不少特性,我在之前的一篇文章就做过介绍:喜大普奔!Kotlin 1.1 Beta 降临~
- tpyealias
- 绑定调用者的函数引用
- data class 可以继承其他类
- sealed class 子类定义的位置放宽
- _ 作为占位,替代不需要的变量
- provideDelegate
关于 Kotlin 的资料,英文版的图书已经出版了几本,主要有:
- Kotlin in Action:这部书已经有了纸质版,是官方自己人写的,算是一本比较权威的参考书了。
- Kotlin for Android Developers:这本书也算是老资历了,稍微看几眼你就会为 Kotlin 有趣的特性所吸引。另外,它还有一个中文的翻译版本
- Modern Web Development with Kotlin:这本书我没有读过,如果你需要用 Kotlin 开发 web 应用,它应该会给予你一些帮助。
- Programming Kotlin:这本书涉及内容非常全面,内容也算是言简意赅,快速入门 Kotlin 可以选择它。
除了图书以外, Kotlin 的首席布道师 Hadi Hariri 已经在 O'Reilly 上面发布了两套视频教程:
里面有免费的几段,且不说内容怎么样,反正考验大家英语听力的时候到了,嗯,老爷子讲得还是很清楚的。
3、Kotlin 时代
1.1 的重要的更新其实就 Coroutine 以及 JavaScript 支持,毕竟 Kotlin 对 Java 的兼容支持已经做得非常不错了(别老提 apt 的事儿,1.0.4 之后的 kapt 不就基本上很好用了么)。别人问我,Kotlin 到底是写啥的,这个问题我通常说很官方的说,Kotlin 是一门运行在 Java虚拟机、Android、浏览器上的静态语言,可是,Kotlin Team 的节奏已经让这句话显得要过时了。他们用短短几年时间搞出这么个全栈的语言,各方面特性都还很棒,然而他们并不能感到满足,他们已经开始走 C++ 的路线,也许 Kotlin Native 要不了多久就会出现了。
第一次听到这消息的时候,我瞬间就凌乱了,那感觉就好像王者荣耀里面队友选了大乔一样,秒回泉水加满血,秒回战场收人头啊。
前不久,我很荣幸地跟一位创业公司 CEO 坐下来聊理想,他问我的第一句话就是:你觉得 Kotlin 是未来么?我当时就蒙了,不得不说,他对 Kotlin 的期待跟 Kotlin Team 如出一辙呀。我当时实在不知道该怎么回答他,回来仔细想了想,答案其实也是有的。
十几年前,东家缺钱,急需投资,投资人坐下来“拷问”小马哥:“这个东西(指当时的 OICQ)怎么赚钱?” 小马哥说自己只知道这个东西大家喜欢,但不知道向谁收钱。对于 Kotlin 来说,我只知道它好用,尽管大家都还看不太懂,不过它的时代正在悄悄的到来。
6. 关于Kotlin语言的一些学习资料
Awesome Kotlin: https://kotlin.link/
Kotlin项目Github源码:https://github.com/JetBrains/kotlin
Kotlin语言规范:http://jetbrains.github.io/kotlin-spec/
在线体验学习Kotlin语言:https://try.kotlinlang.org
官网文档:http://kotlinlang.org/docs/
参考资料
0.https://zh.wikipedia.org/wiki/Kotlin
1.官网提供的一个非常好的交互式Kotlin学习教程:
http://try.kotlinlang.org/
2.List-of-languages-that-compile-to-JS:
https://github.com/jashkenas/coffeescript/wiki/List-of-languages-that-compile-to-JS
3.参考文档:
https://github.com/EasyKotlin/KotlinDoc-cn
4.中文博客文章:
https://www.kotliner.cn/
5.Kotlin中文站:https://www.kotlincn.net/
6.下一代编程语言范式:
http://www.onboard.jetbrains.com/articles/04/10/lop/index.html
Why Kotlin is my next programming language:
https://medium.com/@octskyward/why-kotlin-is-my-next-programming-language-c25c001e26e3
7.https://zh.wikipedia.org/wiki/%E7%A7%91%E7%89%B9%E6%9E%97%E5%B3%B6
8.https://blog.jetbrains.com/kotlin/2017/04/kotlinnative-tech-preview-kotlin-without-a-vm/
9.http://www.oracle.com/technetwork/articles/java/breslav-1932170.html