Kotlin:Google为什么选择用Kotlin

4,981 阅读6分钟

本文标题:Android 开发者自述:为什么我要改用 Kotlin?
本文地址:https://www.oschina.net/news/84980/why-i-turn-to-kotlin
.
对于Kotlin,我一开始是有抵触情绪的,觉得这门语言有点像Js,所以主观地就判定这个语言不好。后面来到新公司,大佬要求新写的代码必须使用Kotlin,于是慢慢喜欢上了这门语言。很多人在学习之前会问,Kotlin到底值不值得学?在这里,我们先不急着回答这个问题,先来看看Kotlin之于Java到底有哪些不一样的地方。

相信很多开发人员,尤其是 Android 开发者都会或多或少听说过 Kotlin,当然如果没有听过或者不熟悉也没有关系。因为本篇文章以及博客后期的内容会涉及到很多关于 Kotlin 的知识分享。

在写这篇文章前的一个多月,Flipboard 中国的 Android 项目确定了正式将 Kotlin 作为项目开发语言,这就意味着新增的代码文件将以 Kotlin 代码格式出现,而且同时旧的 Java 代码也将会陆陆续续翻译成 Kotlin 代码。在使用 Kotlin 的这段时间,被它的简洁,高效,快捷等等特点震撼,所以有必要写一篇文章来谈一谈 Kotlin 的特性,如若能取得推广 Kotlin 的效果则倍感欣慰。

来自知名的工具开发商 JetBrains,也就决定了 Kotlin 的基因中必然包含实用与高效等特征。那我们接下来看一看 Kotlin 的特点,当然这也是我改用 Kotlin 的重要原因。

一,语法简单,不啰嗦

语法简单,不啰嗦
语法简单,不啰嗦

1,Kotlin 支持类型推断,没有 Java 那样的啰嗦。
2,另外用 var 表示变量,val 表示常量更加的简洁
3,方法也很简单,连 function 都缩写成了 fun,平添了几分双关之意。
4,类的继承和实现很简单,使用:即可
5,Kotlin 每个句子都不需要加分号 (;)

二,空指针安全

空指针(NullPointerException 或 NPE)是我们使用 Java 开发程序中最常见的崩溃了。因为在 Java 中我们不得不写很多防御性的代码,比如这样:

Java null
Java null

在 Kotlin 中空指针异常得到了很好的解决。

  • 在类型上的处理,即在类型后面加上?,即表示这个变量或参数以及返回值可以为 null,否则不允许为变量参数赋值为 null 或者返回 null
  • 对于一个可能是 null 的变量或者参数,在调用对象方法或者属性之前,需要加上?,否则编译无法通过

如下面的代码就是 Kotlin 实现空指针安全的一个例子,而且相对 Java 实现而言,简直是一行代码搞定的。

kotlin null
kotlin null

三,支持方法扩展

很多时候,Framework 提供给我们的 API 往往都时比较原子的,调用时需要我们进行组合处理,因为就会产生了一些 Util 类,一个简单的例子,我们想要更快捷的展示 Toast 信息,在 Java 中我们可以这样做。

enter description here
enter description here

但是 Kotlin 的实现却让人惊奇,我们只需要重写扩展方法就可以了,比如这个 longToast 方法扩展到所有的 Context 对象中,如果不去追根溯源,可能无法区分是 Framework 提供的还是自行扩展的。

enter description here
enter description here

注意:Kotlin 的方法扩展并不是真正修改了对应的类文件,而是在编译器和 IDE 方面做得处理。使我们看起来像是扩展了方法。

四,关于kotlin-android-extensions插件

Kotlin不仅在对null类型有很好的处理,在其他很多方面也有很多优势。
接下来来看看kotlin-android-extensions这个插件,说的简单点,这个插件能够代替android里面的findViewById操作,通过这个插件,我们可以直接在Activity,Fragment和View中直接通过xml里面的id来找到view对象,再也不需要使用findViewById这样重复的代码来初始化View对象了。虽然android提供了DataBinding机制来方便开发者来初始化View对象,但是DataBinding在apk打包的时候经常报错,相比Kotlin这点,就没有这个问题,而且使用起来更简洁,基本不需要在代码中做任何初始化操作。另外,ButterKnife这类开源控件虽然也能省略findViewById的操作

五,Lambda, 高阶函数,Streams API, 函数式编程支持

所谓的 Lambda 表达式是匿名函数,这使得我们的代码会更加的简单。比如下面的代码就是 lambda 的应用。
java监听View的回调如下:

mView.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        .....
    }
});
mView.setOnClickListener {
   ......
}

所谓的高阶函数就是:可以接受函数作为参数,也可以返回函数作为结果

举一个接受函数作为参数的例子。在 Android 开发中,我们经常使用 SharedPreference 来存储数据,如果忘记调用 apply 或者 commit 则数据修改不能应用。利用 Kotlin 中的高阶函数的功能,我们能更好的解决这个问题:

enter description here
enter description here

当然这上面的例子中我们也同时使用了方法扩展这个特性。

Kotlin 支持了 Streams API 和方法引用,这样函数式编程更加方便。

al currentFilter = 
mFilterList.filter { it is SearchResultFilter }
        .map { it as SearchResultFilter }
        .find { it.id == "1" }

上面展示的是使用Kotlin中函数式API找到集合中对象类型是SearchResultFilter并且它的id是1的元素。看到这段代码有没有觉得不一样,如果我们用java的话肯定是要使用for循环的,但是使用Kotlin中的filter和map这类的函数却能够让我们在某些时候处理集合的时候更容易,而且也让我们的代码可读性更好。

简单说下filter和map函数的作用,filter能够帮我们过滤出满足条件的元素,但是filter并不会改变这些元素,而map可以改变这些元素,map能够将原来的集合按照给定的操作转换后映射到一个新的集合中去。

Kotlin类型的函数还有find,groupBy,flatMap和flatten等等。这里就不一一介绍了。另外,这种函数配合RxJava食用更佳,相信结合RxJava来写代码你会发觉写出优雅地代码并不是想象的那么难。

六,字符串模板

无论是 Java 还是 Android 开发,我们都会用到字符串拼接,比如进行日志输出等等。在 Kotlin 中,字符串模板是支持的,我们可以很轻松的完成一个字符串数组的组成:

enter description here
enter description here

七,与 Java 交互性好

Kotlin 和 Java 都属于基于 JVM 的编程语言。Kotlin 和 Java 的交互性很好,可以说是无缝连接。这表现在:

  • Kotlin 可以自由的引用 Java 的代码,反之亦然。
  • Kotlin 可以现有的全部的 Java 框架和库
  • Java 文件可以很轻松的借助 IntelliJ 的插件转成 kotlin