先提个问题

Android程序员为什么要学Kotlin?

  1. Java不争气。在1.5时代Java或许还能和C#谈笑风生,而现在C#不知道比Java高明到哪里去了。虽然Java8中也加入了闭包等有用的特性,但Android又不支持……
  2. RxJava 。想象这样一个需求:用户连续点击某个区域10次且每次间隔不超过500毫秒,则触发一个彩蛋。
    实现这个需求很容易,但代码会很混乱。我们得自己控制计时器,保存时间戳,可能还会有令人讨厌的空接口。如果用RxJava来做,几行代码就能搞定。如果再配合Kotlin的函数式编程,简直不能更爽~
    关于RxJava的使用,网上已经有很多了。我有空了可能也会写一些。
  3. 如果你尝试了 Android Databinding ,有没有发现External Libraries里面多了kotlin-runtime和kotlin-stdlib?
    Google内部正是用Kotlin开发的Databinding。虽然短期内Kotlin还不太可能成为Android官方开发语言,但至少这是个好的迹象。
  4. 为什么是Kotlin?

    现在替代Java的选择有很多,Scala、Groovy都能写Android,甚至微软最新发布的Visual Studio都能进来插一脚,为什么要选 Kotlin 呢?
    这又是另一个很大的话题了。请参看大神Jake Wharton的这篇 文章 (要翻墙)。

    那么进入正题。我的学习步骤基本是按照官方的 Reference 来,所以可能写着写着就成了翻译官方文档了……哈哈哈哈

    Function

    最开始学C的时候,我们会说为了实现XXX写个函数(Function),学Java就变成了写个方法(Method),现在Kotlin又变成函数了……
    所以我后面提到Java的时候会说Method,提到Kotlin的时候会说Function,其实都是一个意思~

    先看下Java中的写法

    1
    2
    3
    int sum(int a, int b) {
    return a + b;
    }

    然后是Kotlin

    1
    2
    3
    fun sum(a: Int, b: Int): Int {
    return a + b
    }

  5. 用fun开头
  6. 数据类型写在后面
  7. 结尾不用写分号
  8. 这语法让我想起了Action Script,写惯了Java再来写Kotlin总觉得有些别扭……

    如果想简洁一点可以这样写在一行里,并且返回值类型可以是隐式(inferred)的。不过我个人不太喜欢这样写。

    1
    fun sum(a: Int, b: Int) = a + b

    如果是public function就必须显式的标明返回类型

    1
    public fun sum(a: Int, b: Int): Int = a + b

    没有返回值则用 Unit 关键字

    1
    2
    3
    fun printSum(a: Int, b: Int): Unit {
    print(a + b)
    }

    即使函数是public的,Unit也可以省略掉

    1
    2
    3
    public fun printSum(a: Int, b: Int) {
    print(a + b)
    }

    local variables

    只读变量(read-only)用 val 定义

    1
    2
    3
    4
    val a: Int = 1
    val b = 1 // 如果赋了初始值值,可以省略数据类型
    val c: Int // 否则需要指定类型
    c = 1

    可变变量(mutable)用 var 定义

    1
    2
    var x = 5
    x += 1

    string templates

    ${} 包住变量就行了,这比Java中的String.valueof方便多了

    1
    2
    val a = 1
    print("Value of a: ${a}"}

    conditional expressions

    看起来有点像三元表达式,但可读性更强

    1
    fun max(a: Int, b: Int) = if (a > b) a else b

    nullable values

    写java的同学一定受够了NullPointerException吧。Kotlin与Java很大不同的一点就是显示的标明了value是否可能为空。
    如果可能为空,则用 ? 注明

    1
    var x: Int?

    先知道有这么回事就行了,后面的章节会详细说明。

    type checks & automatic casts

    和C#一样,用 is 操作符来判断变量的类型

    1
    2
    3
    4
    5
    6
    fun getStringLength(obj: Any): Int? {
    if (obj is String) {
    return obj.length // 注意这里obj已经自动转成String类型了,所以可以调用length方法
    }
    return null // 这里obj依然是Any类型
    }

    loop

    和Java相比是把冒号改成了 in

    1
    2
    3
    4
    fun main(args: Array<String>) {
    for (arg in args)
    print(arg)
    }

    while loop

    和Java基本一样

    1
    2
    3
    4
    5
    fun main(args: Array<String>) { 
    var i = 0
    while (i < args.size())
    print(args[i++])
    }

    when expression

    when 可以类比Java中的 switch case ,但是更加强大,可以接受各种操作符

    1
    2
    3
    4
    5
    6
    7
    8
    9
    fun cases(obj: Any) { 
    when (obj) {
    1 -> print("One")
    "Hello" -> print("Greeting")
    is Long -> print("Long")
    !is String -> print("Not a string")
    else -> print("Unknow")
    }
    }

    ranges

    in 操作符太好用了,我就不贴对应的Java代码了,因为想想就觉得麻烦……

    1
    2
    3
    4
    5
    6
    7
    8
    if (x in 1..y-1) 
    print("OK")

    if (x !in 0..array.lastIndex)
    print("Out")

    for (x in 1..5)
    print(x)

    collections

    collections配合in使用很方便

    1
    2
    if (text in names) // 这里调用了names.contains(text) 
    print("Yes")

    如果配合函数式编程和Lambdas表达式就不能更爽……

    1
    2
    3
    4
    names filter { it.startsWith("A") } 
    sortBy { it }
    map { it.toUpperCase() }
    forEach { print(it) }

    注意这里函数前面没有小圆点( . ),这个大概是特有的简写,后面再慢慢学吧~