结论放前面。根据个人的一些了解和受限于经验和眼界,个人认为kotlin是一门非常有潜力的语言,语法糖真的甜,也可实现和Java的混编。Kotlin Native的实现,可以让Kotlin不单单可以通过运行在JVM上实现跨平台,更可以直接生成对应平台上的二进制可执行文件实现跨平台。
在移动端开发领域,Kotlin Native实现了同一份代码既可以在Android平台也可以在IOS平台上运行。而且Kotlin在被Google官宣作为Android的一级开发语言后,在移动端Kotlin的生态绝对得到了保障
但是是否需要完全投入Kotlin还是要打一个问号的,毕竟没有紧迫的需求,系统的稳定才是第一位的。在Web开发领域,Kotlin相对于Java并没有特别高的优势。但是由于Java在老流氓Oracle手中,Kotlin被谷歌大力推行,多学一门学习成本不高的新技术,还是非常值得的。
Kotlin是JetBrains 公司开发的一款运行在JVM上的静态编程语言,其设计目标是创建一种兼容Java的语言。
因为其都是运行在JVM上,所以可以说是兄弟关系,类似的语言还有大名鼎鼎的Scala,Groovy,以及Jython,JRuby等。这一类语言都通过JVM实现了跨平台的特性。
但是Kotlin有所不同的是,它实现了自己的一个编译器Kotlin Native,直接将Kotlin代码编译成可执行的目标平台的二进制文件,而不是字节码,以此实现跨平台的特性。从这点来说,它和Java的关系又远了一些。更远一点来说,Kotlin可以不依赖JVM而实现编译和执行,也就不会存在大量公司到现在还使用Java8进行开发的尴尬局面了。
Kotlin优于Java,网上更多的聊了各种语法方面的问题(在我看来),诚然Kotlin作为一门比较新的语言,并且目标是兼容Java的语言,其针对Java的一些痛点有针对性的做出了改进,让语言变得更简洁,也更“动态”。
但是在介绍语法上的区别之前,我更想介绍一下Java和Kotlin如何实现跨平台的。
因为你觉得不需要跨平台的东西,都是有大佬定义了一堆规范的,比如没事就定义各种协议的IEEE协会。大家都基于一个协议就能方便开发,促进行业发展。但是社会要发展,小弟也想做大哥。基于各种场景和现实需求,会有新的一套规范出来。可能这套规范是老大哥提出的,也可能是小弟提出的。
对于程序开发来讲,我们的平台主要有Windows,Linux,移动端的Android,IOS,以及一些其他IOT设备的一些平台,每个平台底层执行架构的不同决定我们需要不同的机器语言来让告诉机器执行什么命令,无疑是低效的。所以跨平台的语言是大势所趋。
Java实现跨平台是通过JVM来实现的。JVM(Java Virtual Machine)是一种规范,并不是特定的某个编译器。它规定了这个编译器要实现哪些功能,具体的实现由各个厂家实现。目前比较常用的是Oracle JDK,Oracle OpenJDK, Red Hat build of OpenJDK等,以及我们大厂开发的腾讯Kona JDK,阿里巴巴Dragonwell JDK,华为毕昇JDK等。在后文我们用JVM指代字节码的运行时环境。
基于JVM的语言由编译器先编译成字节码文件,字节码文件再运行在JVM中,由JVM负责与OS的交互,因此程序员几乎可以不考虑平台,而只考虑业务逻辑进行编程开发。
JAVA被称为是半静态,半动态的语言。很多博客的解释说是因为Java先通过编译生成字节码文件,然后JVM对字节码进行翻译实行,所以称为半静态,半动态语言。其实我觉得这样说法是有误的。事实上是因为字节码文件在执行初期是使用翻译执行也就是动态语言(例如Python)的执行方式,所以其编译速度很快,但是执行的效率因为没有经过指令优化,因此是比较慢的。但是随着程序的执行,JVM中的JIT(Just-in-time compilation)模块会对其中执行热度高的代码进行编译,生成目标平台的二进制执行文件,这里就用上了指令优化,可以让代码更快的运行,理论上字节码程序运行时间足够长,所有的代码都会被编译,获得更快的运行速度和更少的运行时内存。
因此Kotilin和Java如果都是基于JVM运行,那么JVM带来的优势他们都是可以享受到的。也不会说基于JVM运行的代码比类似C++这类直接编译生成可执行文件的编程语言运行慢的问题。
这里最大的问题是,通用的JDK大家都使用Oracle JDK8而不是其最高版本,因此也享受不到高版本的JDK新特性,可能这也就是大厂自研JDK的一部分理由
先看看官方的解释
为什么选择Kotlin/Native
Why Kotlin/Native?
Kotlin/Native is primarily designed to allow compilation for platforms where virtual machines are not desirable or possible, for example, embedded devices or iOS. It solves the situations when a developer needs to produce a self-contained program that does not require an additional runtime or virtual machine.
Kotlin/Native主要设计为允许编译不需要或不可能使用虚拟机的平台,例如**嵌入式设备或iOS。**它解决了开发人员需要生成不需要额外运行时或虚拟机的自包含程序的情况。
传闻IOS不能使用Java开发的一个原因就是因为基于JVM运行,不够安全(在运行时可以通过classLoader加载新的类,理论上可以安插一些恶意代码)和IOS的思想不符合。
再看看目前Kotlin Native支持的平台
Kotlin/Native supports the following platforms:
- iOS (arm32, arm64, simulator x86_64)
- macOS (x86_64)
- watchOS (arm32, arm64, x86)
- tvOS (arm64, x86_64)
- Android (arm32, arm64, x86, x86_64)
- Windows (mingw x86_64, x86)
- Linux (x86_64, arm32, arm64, MIPS, MIPS little endian)
- WebAssembly (wasm32)
可以看到主流的一些平台都是有支持的,包括可以运行JVM的Windows和Linux。其实Kotlin Native的重点还是在于可以打通Android和IOS平台。官方文档表达的意思也是如此,例如下面的描述:
It is easy to include a compiled Kotlin code into existing projects written in C, C++, Swift, Objective-C, and other languages. It is also easy to use existing native code, static or dynamic C libraries, Swift/Objective-C frameworks, graphical engines, and anything else directly from Kotlin/Native.
主要还是集中在Android开发和IOS开发。但是这个用词非常的熟悉。因为之前多次看到这样一句话“Kotlin可以方便的利用现有的Java库”。
具体的Kotlin Native性能方面的资料较少,这里也可以和JVM的各种资料做个对比,虽然Kotlin也是开源的,但是社会上的热度明显还是低于Java。
Native相对于JVM来说,因为直接编译成二进制文件,做了指令优化,所以编译的时间会更久,执行的速度会更快。但是JVM长时间运行后的效率未测**(TODO)**但是根据社区反馈也有一些优化上的问题(例如SIMD),但是背靠JetBrains以及谷歌,肯定也不赖。
一门语言基础语法决定了入门的难易程度。比如津津乐道的大学为什么首选编程语言是C而不是Python。从我的角度来说Python作为一门动态语言,语言的习惯和英语更像,而且没有很多的条条框框。跟重要的是C需要考虑内存,指针而Python什么都不需要,也不太需要了解数据类型。大量的工作交给编译器自动进行了。
Java作为后来的高级编程语言,屏蔽了指针这个比较抽象的概念,保留了变量需要严格数据类型定义的特性,简单容易上手,又方便管理。但是相对于灵活的动态语言来说,还是条条框框太多了。因此Kotlin作为目标是兼容Java的语言,针对Java的一些冗长表达,结合其他语言的优秀特性,建立了一套自己的语言规范。
什么是语法糖
其实上述讲的语言的优秀特性都属于广义的语法糖的范围。语法糖其实是指一些某种计算机语言中的某种语法(某种表达式或者函数),这种语法对语言的功能没有影响,或者说没有突破性的改变,但是他包装了程序员的一些常用但是实现复杂的一些操作,实现用简短的表达式实现某种功能,增加程序的可读性,提高程序员编程效率。
两个例子
C++中对二位数组的取值
// 取二维数组中第i行第j列
*(*(a+i)+j);
//语法糖
a[i][j]
Python中对数组的切片操作
## 包含六个数的数组
a = [1,2,3,4,5,6]
## 复制一个新的数组
b = a[:]
## 取前三个
c = a[:3]
## 取第3-6个数
d = a[2:5]
## 读取倒数第二个数
a[-2]
基础语法和语法糖很难分开介绍,而且专门的基础语法介绍又比较繁琐冗长。因此接下来的介绍仅介绍我觉得必须了解的部分语法以及印象深刻的语法糖。详细的基础语法可以看菜鸟教程。作为可以兼容Java的语言,其语法特点和Java其实是很相似的,我也会把Java和Kotlin的语法进行一个对比(以JDK8为标准)
作为写程序用得最多的语法,如果能少敲几下键盘,但是又不影响程序的理解,何乐而不为呢?
关键字fun:定义一个函数。参数格式为:参数名称 : 类型
kotlin中很神奇的一个地方就是将参数的类型放到了参数名称之后。虽然没有人要求参数类型一定要在参数名称的前面,kotlin官方的解释是这样更为直观,笔者不置评论。
kotlin中函数的定义借鉴了很多动态语言
// 标准格式
fun sum(a: Int, b: Int): Int {
// Int 参数,返回值 Int
return a + b
}
// 返回类型自动推断
fun sum(a: Int, b