WeTest腾讯质量开发平台 Android 平台的 Swift—Kotlin

腾讯WeTest · 2018年05月03日 · 最后由 胖虎 回复于 2018年05月04日 · 2117 次阅读

作者:yunnan, 腾讯移动客户端开发工程师
商业转载请联系腾讯 WeTest 获得授权,非商业转载请注明出处。
原文链接:http://wetest.qq.com/lab/view/383.html

WeTest 导读

Kotlin 已经出来较长一段时间了,有些同学已经对 Kotlin 进行了深入的学习,甚至已经运用到了自己的项目当中,但是还有较多同学可能只是听过 Kotlin 或简单了解过,这篇文章的目的是让这些同学对 Kotlin 有一个系统全面的认识,让有兴趣的同学在之后学习的时候能更加的轻车熟路。


什么是 kotlin?

一、一门静态编程语言

跟 java,c 一样的强类型语言,变量的数据类型在编译时确定。对比的 JavaScript,python 则是动态编程语言。

二、JetBrians 开发设计

一家捷克的软件公司,是著名的 IDE 开发商,对很多的开发语言和平台都提供了相应的集成开发环境,比如 Java 的,OC 的,JavaScript,PHP,C/C++ 等。而其中最著名的是 IntelliJ IDEA ,Java 的集成开发环境,被称为目前最好用的 java IDE。而且 Android Studio 就是 Google 基于 IntelliJ IDEA 开发的,由此可见 Google 和 JetBrains 的合作也是比较密切的。而从以上说明也可以看到 JetBrains 不仅实力强劲,这家公司对于语言设计更是有天然优势。Kotlin 是集多家语言之大成。

三、Kotlin 是开源的 (基于 Apache 2.0 开源许可协议)

我们在 GitHub 上可以下载 Kotlin 的全部源代码。而且可以自己进行代码修改,再发布。

https://github.com/JetBrains/kotlin

最新版本已经更新到了 1.2.3 。

四、Android 官方开发语言

JetBrains 其实在 2011 年就推出了 Kotlin, 在之后的很长一段时间都处于设计,开发和完善当中,2016 年才发布第一个正式版本,而在 2017 年 5 月份的 Google I/O 开发者大会上,被 Google 宣布称为 Android 的官方开发语言。

被程序员们称为 Android 平台的 Swift。

Kotlin 有哪些优势?

一、 语法简洁,且吸收了很多其他语言的优点

大量的语法糖(有函数声明,类的创建,集合相关,范围运算符等等大量简洁的语法)、 Lambda 表达式(Java8 支持),简洁的函数表示法,后面会介绍到。

可参考:http://qinghua.github.io/kotlin-syntax-suger/ 收集的语法糖们。

吸收其他语言的优点有:模板字符串,运算符重载,方法扩展,命名参数等。后面在语言新特性中会讲到。

二、安全性

空安全:避免空指针异常。当变量可以为 null 时,必须使用可空安全符?进行声明,否则会出现编译错误。声明变量为可空后,在运行时便不会抛出异常。

类型智能转换:通过 is 进行类型判断后,编译器自动进行类型转换。父类引用可以调用子类接口,注意转换只在 is 的代码块中生效。

三、完全兼容 Java

类似于 swift 于 OC 的关系,虽然官方推荐使用新语言 Kotlin 进行 Android 开发,但是前提新语言必须兼容旧语言(否则是无法得到 google 的认可的)。所以 Kotlin 的设计初衷就是要完全兼容 Java。

相互调用:使用 Kotlin 进行 Android 或者 Java 服务端开发,可以导入任意的 Java 库。Kotlin 和 Java 之间可以相互调用。

相互转换:在 Android Studio 中可以一键转换 Java 代码为 Kotlin 代码(Code > Convert Java File to Kotlin File.)。同时 Kotlin 代码也可以反编译成 Java 代码(1.Tools>Kotlin>Show Kotlin Bytecode 2.Decompile)。

Java 的 API = Kotlin 的 API。

四、工具支持

JetBrains 为 Kotlin 的开发提供了大量的工具支持。我们可以直接下载 Kotlin Compiler 库在命令行进行编译和运行,也可以通过安装插件在 Eclipse 中使用 Kotlin,而现在 IntelliJ IDEA 和 Android Studio 已经可以直接使用 Kotlin 进行开发。就像 JetBrains 所说:一门语言需要工具化,而在 JetBrains,这正是我们做得最好的地方!

Kotlin 如何兼容 Java?

我们来看一张图,了解 Kotlin 的编译过程。

Kotlin 为什么可以兼容 Java,一个主要原因是 Kotlin 文件在经过 Kotlin 编译器编译后会生成 Java 字节码。这跟 Java 文件通过 Java 编译器编译后生成的字节码几乎没有区别,这样 JVM 就能直接识别和处理 Kotlin 代码的功能和逻辑。

当 Kotlin 调用 Java 代码,Kotlin 编译器会对调用的 Java 文件进行分析,以便 kt 文件能够生成正确的 class 文件。为什么这么说呢?举个列子,Java 字节码有几种函数调用的方式 invokespecial 、 invokeStatic 、 invokeInterface 等,编译器必须知道调用的 Java 函数是什么类型才能生成相应的正确的字节码。而当在 Java 代码中调用 Kotlin 对象时,Kotlin 生成的 class 文件也要输入到 Java 编译器,这时 Java 文件才能生成正确的 class 文件。生成的 class 文件打成 jar 包后,最终可以生成 Android 的 APK,或供 Java 服务端调用。

我们可以直接下载下载 Kotlin 编译器下来查看他的编译过程(最新https://github.com/JetBrains/kotlin/releases/tag/v1.2.40-eap-16Kotlin 编译器的代码都是用 java 写的,所以使用 Kotlin 编译器必须要有 java 环境。)。

** Kotlin 的语言特性 **

一、基础特性

1、 定义变量

Var 用来声明变量,Val 类似 Java final,用来声明常量。语句后面不需要跟分号。变量类型可以根据变量值进行自动推导。这里 Kotlin 的基础类型都是对象,使用的是 Java 的包装类(基础类型包装成对象)。

2、定义函数

函数使用 fun 为关键字进行声明。变量的冒号之后是变量类型,函数的冒号之后是返回值。

同时我们可以在定义函数的时候声明参数的默认值。

函数调用的时候可以直接调用,也可以使用命名参数:

使用命名参数可以增加可读性,减少函数的重载。

3、类的声明

类名的冒号表示继承,所有类的基类称为 Any(并不是 Object,只包含 equals、hascode、toString 方法)。声明构造函数要指明 constructor 关键字。

也可以直接在声明类的时候指定构造函数。

对象实例化可以不写 new 关键字:


数据类,用来保存 Info 数据的类,其实就是 JavaBeans。这里使用一句代码创建一个包含 getters、 setters、 equals()、 hashCode()、 toString() 以及 copy() 的 类。

4.、流程控制

其他流程控制基本跟 Java 差不多,这里主要讲下 when 表达式,他取代了 Java 的 switch

when 表达式其实最终是使用 if/else 来实现的。

保留了原来的 for each 循环,同时增加了区间控制

5、集合

Kotlin 的集合与 OC 的集合相似,分为可变集合和不可变集合(lists、sets、maps 等)。

kotlin 中的可变集合对 Java 的集合进行了包装,同时它实现了一套不可变集合库。

访问:

6、伴生对象

Kotlin 中没有静态属性和方法。如果我们要创建单列,可以使用 Object 关键字声明类。

如果要在一个类里面声明静态成员,可以在类的内部使用伴生对象。使用关键字 companion object

调用的话,直接跟 Java 一样,通过类名点属性名称或函数名称调用。

二、新特性

1、空安全

Kotlin 是如何实现空安全的呢?

在 Kotlin 中,对象声明分为可空引用和非空引用两种。

非空引用:

可空引用:

安全调用操作符,写作 ?. 可空调用:

通过函数调用给可空引用赋值,返回的必须也是可空引用。这就在编译期间杜绝了空指针异常。但是这里要注意一点,如果从 Java 返回的集合,不会强制做可空检查,这个是时候如果给不可空引用赋值 Java 集合中的 null 会出现转换错误异常。

2、扩展函数

跟 OC 的 Category 一样,可以对 API 的函数进行扩展。

我们在任意 Activity 中都可以直接调用

函数扩展并不是修改了原来的类,通过反编译成 Java 代码可以发现,函数的扩展是通过静态导入的方式实现的。

3、字符串模板

表示字符串中可以包含变量或者表达式,以 $ 符号开头(这跟 JSP 的 EL 表达式有点像),比如:

Kotlin 中是通过单引号进行转义的

4、操作符重载

Kotlin 为基本的运算符提供了固定名称函数表,比如

示例:

调用:

5、Lambda 表达式

Lambda 本质上是一个未声明的函数,他会以表达式的形式传递。既然是函数,就由这三块组成:参数 、 方法体 和 返回值。

我们来看一下完整的 Lambda 表达式是怎么写的:

大括号内,箭头左边是参数,箭头右侧是方法体和返回值。这里传入两个 Int 类型的参数,返回一个 Int 类型的值。

声明一个接受函数为参数的函数:

第二个参数 rightV 表明接受的是一个函数,函数有两个 Int 型的入参,返回一个 Int 型的输出。

调用:

在 Android 中使用 Lambda 表达式,可以写成

省略了函数的括号。这里原本不是传入函数类型参数,是编译器做的处理。

注意:listener 有多个接口声明时,不能这么使用,比如 setOnCheckedChangeListener

三、高级特性

1、高阶函数

把函数作为参数或者是返回值的函数,Kotlin 称之为高阶函数。比如函数:

就是一个高阶函数。可以这么调用:

我们声明一个局部函数,然后把他作为参数传递给另一个函数。我们还可以使用 Lambda 表达式来表示函数参数。

2、泛型

泛型的存在主要是为了消除模板代码和类型转换安全, 在 Kotlin 中泛型的使用基本与 Java 是一致的。

在 Java 中泛型是不变的,比如:虽然 A 继承 B,但 List和 List之间没有任何关系,Java 是通过泛型通配符来实现型变的:

<? extends T> 对应 Kotlin 的 out T 生产者

<? super T> 对应 Kotlin 的 in T 消费者

PECS 原则 : producer-extends, consumer-super

但是 Kotlin 中使用比 Java 的更加灵活,比如可以在类声明的时候添加型变 , 或者函数声明的时候添加。

更多可以了解:https://segmentfault.com/a/1190000010313252 写的非常详细。对 Java 泛型理解的不是很透彻可以再看看 http://www.importnew.com/24029.html

3、反射

在运行时获取类的方法,属性,类结构等所有信息。

1)Kotlin 中使用 Java 的反射

jc 返回的是 Java 的 class 对象,可以通过这个对象去调用调用 Java 的反射。

2)Kotlin 中的反射:

可以不通过 KClass 对象,直接调用方法和访问属性(注意:如果有重载的函数或同名的属性不能使用以下方式)。

4、协程

什么是协程?

协程是一种新的异步编程方式,它使用线程为资源,基于代码逻辑去实现任务之间的调度。它主要是由编译器去实现的。

程序使用协程可以书写线性的异步代码,没有 callback,大大简化了异步编程。线程有的异步操作协程都支持,协程的挂起和切换非常轻量基本没有开销。

如何使用协程?

协程目前虽然还在试验阶段,但是功能已经非常完善了(现在 Kotlin 最新 1.2.3 版本,预计 1.3 会删除实验室状态)。有兴趣的同学可以参考:

https://www.kotlincn.net/docs/tutorials/coroutines-basic-jvm.html

kotlin 跨平台

一、多平台支持

Kotlin 的不仅仅用于 Java,JetBrains 的野心远不止于此。使用 Kotlin 同时可以用于其他平台的开发。所以市面上之前说 Kotlin 是一款基于 JVM 的语言是不准确的。

Kotlin 用于服务端开发:

使用 Kotlin 可用于 Java 服务端开发。Java 与 Kotlin 的相互兼容性,我们可使用服务端的任意框架,同时我们可以保留老的 Java 代码,使用 Kotlin 编写新代码。Kotlin 的协程特性更有助于构建服务端程序。IDE 的支持和 Sring 框架的支持。

Kotlin 用于 Android 开发:

Android Studio 的支持。大量的实际案列。大量可学习的 APP 项目。与 Java 兼容性允许在 Kotlin 应用程序中使用所有现有的 Android 库。

Kotlin 用于 JavaScript:

使用 kotlinc-js 编译器将 Kotlin 代码转换为 JavaScript(不是 Kotlin 或标准库的代码编译时会被忽略),Kotlin 中提供了一些标准库用于 JS 开发,同时可以使用第三方 JS 库。

Kotlin Native:

Kotlin/Native 是一种将 Kotlin 编译为没有任何虚拟机的原生二进制文件的技术。还在开发中,现在只出了预览版本。

预览版本支持: Window 、 Mac 、 IOS 、 Android 等平台。Kotlin 代码最终会编译成一个 kexe 文件,直接打开就可以运行。

基于 Kotlin/Native 的一款游戏源码:https://github.com/jetbrains/kotlinconf-spinner

二、开发多平台项目

Kotlin 多平台项目允许你将相同的代码编译到多个目标平台。 目前支持的目标平台为 JVM 与 JS,即将增加 Native。

目前还是 1.2 新版本的一个实验性功能。

多平台项目由三种类型的模块组成:

● 公共模块

公用模块只包含与平台无关的 Kotlin 代码以及 Kotlin 公共标准库代码。同时还包含不含实现的平台接口声明。

● 平台模块

平台模块可以依赖在指定平台上可用的任何模块与库(包括对于 Kotlin/JVM 平台的 Java 库与 Kotlin/JS 平台的 JS 库)。

● 常用模块

与平台模块相互依赖的模块


我对 Kotlin 的看法


1、确实是一门很优秀的语言。语言简洁,包含各种语言的优秀特性。但是一些亮点的特性包含协程和多平台都处于试验和开发阶段。并不能吸引除 Java,Android 之外的更多开发者加入(JS 平台使用的人并不多)。

2、与 Java 的交互性,让它能够依赖 Java 成长。但是对 Java 的依赖和兼容性注定无法完全替换 Java。

3、虽然获得 Google 认可,但是 Kotlin 语言的热度一直在逐渐下降,发文之前在 TIOBE 排行榜已经降至 49 位。我猜测虽然 Kotlin 获得经验丰富的程序员的青睐,但是对于初中级选手来说他们更愿选择 Java 这门熟悉的语言。

4、潜力是巨大的,毕竟有 Google 的官方支持和 JetBrains 的强劲实力做支撑。如果之后 Kotlin 在多平台等实验室特性上有所突破的话,绝对会吸引更多的开发者。

学习资料汇总


1.Kotlin 官网

http://kotlinlang.org/

2.kotlin 中文官网

https://www.kotlincn.net/

3.Google Kotlin 项目学习实例

https://developer.android.com/samples/index.html?language=kotlin

4.阿里巴巴工程师教学系列文章

https://segmentfault.com/u/donghaichenguangjian

5.Kotlin 协程

https://www.jianshu.com/p/9f720b9ccdea

https://github.com/Kotlin/kotlin-coroutines/blob/master/kotlin-coroutines-informal.md

https://github.com/Kotlin/kotlinx.coroutines/blob/master/coroutines-guide.md

6.其他文章

https://blog.csdn.net/u013448469/article/details/79403284 Kotlin 反射

https://blog.csdn.net/ztguang/article/details/72511994 Kotlin Native


腾讯 WeTest 自动化兼容测试提供云端自动化兼容服务,提交云端百台真机,并行测试。快速发现游戏/应用兼容性和性能问题,覆盖安卓主流机型。目前已经支持所有腾讯在研和运营的手游项目。

欢迎点击链接:http://wetest.qq.com/product/auto-compatibility-testing 使用专家兼容测试服务。WeTest 兼容性测试团队期待与您交流!You Create,We Test!

如果对使用当中有任何疑问,欢迎联系腾讯 WeTest 企业 qq:800024531

腾讯 WeTest 有奖征文活动进行中,欢迎投稿!了解详情:
http://wetest.qq.com/lab/view/379.html

共收到 3 条回复 时间 点赞

有些图挂了

不好意思已修正

总结的挺好的,但是我感觉 swift 和 OC 比更愿意用 OC(适应了 OC 的语法后觉得确实不错),拿它跟 Kotlin 比的话,是不是有点不恰当?呵呵

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册