在今年的 Google I/O 大会上,Google 宣布在 Android 上为 Kotlin 提供一等支持(转为正房)。

在 Andorid 开发的圈子中,这无疑掀起了轩然大浪。对部分人来说,也许这是第一次听到 「Kotlin 」。事实上,在2011年7月,JetBrains 就推出 Kotlin 项目,直到去年2月份 Kotlin v1.0 才正式发布。

本系列文章「Dive Into Kotlin」将会对 Kotlin 进行较为系统的介绍,大致分为四个章节:

  1. 热身 —— Kotlin 基本特性
  2. 下水 —— Kotlin 核心
  3. 潜入 —— Kotlin 与函数式
  4. 遨游 —— kotlin 与 Android 实战

本文将简单介绍 Kotlin 的生态系统和部分语言功能。

Kotlin 是一门怎么样的语言?

Kotlin 是一种在 JVM 上运行的静态类型编程语言,可以编译成Java字节码,也可以编译成 JavaScript,方便在没有 JVM 的设备上运行。

Kotlin 核心的目标

  • 简约:帮你减少实现同一个功能的代码量。

  • 易懂:让你的代码更容易阅读,同时易于理解。

  • 安全:移除了你可能会犯错误的功能。

  • 通用:基于 JVM 和 Javascript,你可以在很多地方运行。

  • 互操作性:这就意味着 Kotlin 和 Java 可以相互调用,同时 Jetbrains 的目标是让他们 100% 兼容。

对比 Java,Kotlin 或许显得有点年轻,但这并不代表它的生态系统不够稳定。

强大的生态圈

Kotlin 编译为 JVM 字节码或 JavaScript
它可以吸引所有使用垃圾回收机制语言的程序员,包括 Java,Scala,Go,Python, Ruby 和 JavaScript。

kotlin 产自工业,而不是学术界。
它解决了程序员目前所面临的一些问题。举个例子:类型系统可以帮助你避免空指针异常。当我们在使用一些 API 或者大型库时判断是否为 null,往往没有什么实际作用。

Kotlin 完美兼容 Java
在 Idea 中,你可以一键实现 Java 与 Kotlin 的转换。也就是说, Kotlin 写的项目中可以使用所有现有的 Java 框架和库,甚至是依赖于注解的高级框架,并且它整合了 Maven,Gradle 和其他构建工具——帮助我们实现无缝的互操作。

Kotlin 相对入门简单
所以正如大家所说的那样,Kotlin 是一门十分友好的语言,你甚至可以花几个小时阅读下相关书籍就能入门。它的语法简洁直观,也许大多时候看起来比较像 Scala,实际上简单了很多。这种语言很好地平衡了简洁和可读性。

不施加运行时间的开销
标准库是比较小的:主要是对 Java 标准库的重点扩展。大量使用编译时内联(compile-time inlining)就意味着像 mapfilterreduce 这样的语法编译起来与命令式的相似。

Android扩展库
Ankokovenant 让 Kotlin 在 Android 的开发中更加方便,如果你看过这两个库,一定也为之青睐。

除 Android 外,其实企业级别的 Java 项目也可以考虑使用 Kotlin:

  1. 它有一个成熟的公司强大的商业支持,JetBrains 致力于该项目的房展,拥有一支高效的团队和稳定的商业模式。在较长的时间内,你都不用担心 Kotlin 被抛弃。

  2. Kotlin 的风险很低:可以由一两个成员尝试在某个功能块使用,但并不会影响其他模块:Kotlin 类可以导出一个与常规 Java 代码看起来相同的 Java API。

  3. Java 6 废土中的一线希望:如果升级 JVM 对于你们的成本很高,你可以使用 Kotlin,它是「加强版的 Java 6」。

看完生态系统,来看看最吸引我们的语言功能。

特征

kotlin&&Android

属性前置

Java Bean 中总是出现一些重复工作量的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class Customer{
String name;
int age;
public Customer(String name, int age){
this.name=name;
this.age=age;
}
public String getName(){
return name;
}
public int getAge(){
return age;
}
public setName(String name){
this.name=name;
}
public setAge(int age){
this.age=age;
}
}

在 Java 对象中,构造函数和属性的 GetterSetter 函数在每个Bean类中都会出现,看起来非常冗余。

但是使用 Kotlin,代码是这样的:

1
data class Customer(val name:String, val age:Int)

Kotlin 将GetterSetter 等函数省略,让我们更加关注属性。

函数式编程是变革的关键

如果你是一名 「FP」 (Functional Programming) 爱好者,你肯定知道 Scala 这门语言。而 Kotlin 的设计初衷就是提供 Scala 里的很多特性,但不被编译时间束缚。

FP

网上对函数式编程的介绍,大多数对初学者都是不够友好的,下面是一种比较简洁的概括:

函数编程以基于数学的函数构成,实现一个功能时倾向于实现的目标,而不是实现目标的方式。

也就是说,函数式编程处理的是不可变的数据,即不会改变变量的值。它所做的只是 Receive(接收)-> Compute(计算)-> Return(返回) ,而不改变它接收到的值,或者引起「副作用」

Kotlin 重新定义了函数的写法

  • 简化函数重载。
  • 命名参数不遵循顺序:命名参数允许完全控制什么值被传递给变量,并在与布尔处理,举个例子:
1
2
3
4
5
6
7
8
9
10
11
12
13
// Java
void check(boolean isAlpha, boolean isNum){//函数定义
}
check(truefalse); //函数调用
// Kotlin
fun check(isAlpha:Boolean, isNum:Boolean = false) {
// do something
}
check(true)// 1
check(true,true)// 2
check(isAlpha = true, isNum = false) // 3
check(isNum = false, isAlpha = true) // 4

其中1、3、4实际效果一致。

函数可读性

  • 单行表达式是提高代码可读性的第一步。
1
2
3
4
5
6
7
int sum (int x,int y){ // 返回类型必须声明。
X = X + Y; // x的值被改变,是一个副作用。
return x;
}
// kotlin
fun sum(x:Int, y:Int)= x + y //完美。

在 Android 开发时,我们应该都会对视图的 onClick 事件感到烦躁。

1
2
3
4
5
6
7
// Java
view.setOnClickListener(new View.OnClickKistener() {
@ Override
public void onClick(View v){
System.out.println("sad");
}
});

在 kotlin 中,这也得到简化:

1
2
3
view.onClick {
println("nice !!"
}

类型安全

在 Android 开发中,出现 NullPointerExceptio 已经可以说是家常便饭了,在运行的时候才出现这个异常,对用户体验造成的损失是巨大的。

Kotlin 能很好的避免这个问题:

  • 指定 null
    1
    2
    3
    4
    5
    6
    // Java
    String text1 = null // NE
    // Kotlin
    var text1:String = "Kotlin"// 正常
    var text2:String = null // NE
    var text3:String?= null // 正常

Kotlin 中只有加了 ? 才允许为null。

  • 检查 null
    Kotlin 可以通过 ?确保安全调用:

    1
    2
    3
    4
    5
    6
    // Java
    if(a != null){
    int x = a.length();
    }
    // Kotlin
    val x = a?.length //仅当a不为null时才编译
  • 为 null 时默认值

    1
    2
    3
    val x = b?.length ?: 0 // 如果b为 null,那他的 length 就为0
    val x = b?.length ?: throw NullPointerException()
    val x = b!!.length

Lambda 优化

Lambda 表达式增加了 Kotlin 的简洁功能,从而也带来了易理解的代码。(Java 6 不支持 lambda )

1
2
val sum = {x:Int,y:Int - > x + y} //类型:(Int,Int) - > Int
val result = sum(2,7// result == 9

条件判断更优雅

在 kotlin 中 when 也能给你惊喜:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//Java
if(x==1)
println("x is 1");
else if(x==2)
println("x is 2");
else if(x==3||x==4)
println("x is 3 or 4");
else if(x>=5||x<=10)
println("x is 5, 6, 7, 8, 9, or 10");
else
println("x is out of range");
//Kotlin
when (x) {
1 -> print("x is 1")
2 -> print("x is 2")
3, 4 -> print("x is 3 or 4")
in 5..10 -> print("x is 5, 6, 7, 8, 9, or 10")
else -> print("x is out of range")
}

当然除了以上这些,Kotlin 还有许多令人惊喜的特性,将会在后续的文章中详细介绍,敬请期待。