五分钟学会 Kotlin 语法

为什么使用Kotlin

项目一期在收尾了终于有时间折腾了,一个多月以来 Kotlin 从入门到现在,坚持用来开发的切身感受。因为语法与 Java 的区别挺大的一开始很想放弃,如果不是因为项目在使用,想必很少人会尝试这样一门小众语言,但是习惯后会发现这些年究竟浪费多少时间在写无用的 Java 代码了, Kotlin 在兼容 Java 的基础上还能大大提升开发效率。Kotlin 有许多特性但对于开发来说,快速适应和学习更为重要,很多时候我们都是在不明白其原因就开始使用的,正如我们不可能把 Retrofit 原理研究透才使用它。只要它足够稳定成熟,并能有效的提升开发效率都是值得尝试的。鄙人不才,目前使用 Kotlin 的原因主要是因为它语法简洁,支持 lambda 表达式,强大的 when 语法,不用写分号结尾,光是这些就足以让我喜欢 Kotlin。至于空安全之类的特性,毕竟服务端数据类型太多 null 了并没多大感触,这些特性在实际应用中潜移默化的就吸收了,以至于现在遇到几个Java编写的代码,都有些不适应了。

修改说明

突然火了一脸懵逼,Google IO 的影响真是不容小觑。避免误人子弟还是修改下比较好,也就把上一篇文章的基础知识也搬迁过来,对条件判断when还有空判断处理进行了修改,添加了lambda说明,移除过期链接。

Kotlin 基本语法

先说个学习 Kotlin 语法的小窍门,将代码用 Java 写好,然后 Code/Conver Java File to Kotlin File 转换成 Kotlin 代码,或者将 Java 代码复制到 Kotlin 文件会提示转换也是挺方便的,比较差异很容易就能理解了,一开始难免不适应习惯后相信你一定会喜欢上Kotlin

1). 定义

忘掉 Java 的那一套写法不然会很不适应的,Kotlin 有自己的特性不该被 Java 的思维所束缚。在 Kotlin 中常量用 val 声明,变量用 var 声明,关键字在前面,类型以冒号:隔开在后面,也可以省略直接赋值,类型后带问号?表示可为空类型(默认空安全)。
常量 val 延迟加载 by lazy{},默认线程安全关闭线程安全 lazy(LazyThreadSafetyMode.NONE){},变量 var 延迟加载 lateinit。

//常量数组int[][][] arrs = new int[3][2][1];
val arrs = Array(3) { Array(2) { IntArray(1) } }
//空安全变量
var str: String = "hello"
var str1 = "word"
//可为空字符串变量
var str2: String? = null

2). 条件

if…else 正常使用,不过移除了 switch 用更强大的 when 替代,when 子式可以是常量、变量、返回数值的表达式、返回 Boolean 值的表达式,强大到用来替换 if…else if

// 测试值 x = 0, -1, 1, 2, 3, 6, 10
var x = 10
when (x) {
    //常量
    2 -> println("等于2")
    //数值表达式
    if (x > 0) 1 else -1 -> println("大于0并等于1,或小于0并等于-1")
    //Boolean类型表达式
    in 1..5 -> println("范围匹配1-5")
    !in 6..9 -> println("不是6-9")
    is Int -> println("类型判断")
    else -> println("else")
}
// 代替if...else if
when{
    x > 6 && x <= 10  ->  println("大于6小于等于10")
    x < 6 -> println("小于6")
    else -> println("else")
}

3). 循环

while 和 do…while 同 Java 并无区别,for 则有很大改变并多出了几个变种

val list = ArrayList<String>()
//递增for (int i = 0; i < list.size(); i++)
for (i in list.indices) {
   print(list[i])
}
//递增for (int i = 2; i < list.size(); i++)
for (i in 2..list.size-1) {
   print(list[i])
}
//递减for (int i = list.size(); i >= 0; i--)
for (i in list.size downTo 0) {
    print(list[i])
}
//操作列表内的对象
for (item in list) {
    print(item)
}
//加强版
for((i, item) in list.witnIndex()) {
    print(list[i])
    print(item)
}
//变种版
list.forEach {
    print(it)
}

list.forEach {
    print(it)
}

list.forEachIndexed { i, s ->
    print(list[i])
    print(s)
}

list.forEachIndexed(object :(Int,String) -> Unit{
    override fun invoke(i: Int, s: String) {
        print(list[i])
        print(s)
    }
})

万能的冒号

在 Kotlin 中冒号:用万能来称呼绝不为过。常量变量的类型声明,函数的返回值,类的继承都需要它

//val表示常量var表示变量声明
val name: String = "tutu" 
//省略类型说明
var age = "23"
//fun表示函数
fun getName(): String{
   return "tutu"
}
//类继承
class UserList<E>(): ArrayList<E>() {
    //...
}

除此之外还有一个特别的地方也需要它,使用 Java 类的时候。Kotlin 最终会还是编译成 Java 字节码,使用到 Java 类是必然的,在Kotlin语法如下

val intent = Intent(this, MainActivity::class.java)

类名::class.java没有为什么就这么写记着就是

我是谁的@

除了冒号另一个重要符号@,想必用到内部类和匿名内部类的地方一定很多,再加上支持 lambda 语法,没有它谁告诉你 this 和 return 指的是哪一个

class User {
    inner class State{
        fun getUser(): User{
            //返回User
            return this@User
        }
        fun getState(): State{
            //返回State
            return this@State
        }
    }
}

偷懒的方法

1). Kotlin 特色

Java 的 getter/setter 方法自动转换成属性,对应到Kotlin属性的调用

public class User {
    private String name;
    private String age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAge() {
        return age;
    }

    public void setAge(String age) {
        this.age = age;
    }
}

反之 Kotlin 的属性自动生成 Java 的 getter/setter 方法,方便在 Java 中调用,同样的定 义在 Kotlin 中

class User {
    var name: String? = null
    var age: String? = null
}

这样一个Java类在Kotlin中只需这样调用

val user = User()
//赋值
user.name = "tutu"
user.age = "23"
//取值
val name = user.name
val age = user.age

我们的 getter/setter 方法有时不会这么简单,这就需要自定义 getter/setter 了,另起一行设置 get()/set(value) 方法,实现一个 Java 中常用的单例,这里只为了展示,单例在 Kotlin 有更简单的方法实现,只要在 package 级别创建一个 object 即可

class User {
    companion object {
        @Volatile var instance: User? = null
            get() {
                if (field == null) {
                    synchronized(User::class.java) {
                        if (field == null)
                            field = User()
                    }
                }
                return field
            }
    }

    var name: String? = null
    var age: String? = null
}

自定义 getter/setter 重点在 field,跟我们熟悉所 Java 的 this 指代当前类一样,field 指代当前参数,直接使用参数名 instance 代替不会报错但单例就没效果了

2). 字符串模板

在 Java 中拼接字符串的代码可读性都很差,在 Kotlin 字符串拼接变得非常简洁,只需用 $ 后面加上参数名,复杂的参数要加上{}

val user = User()
//赋值
user.name = "tutu"
user.age = "23"
//取值
val name = user.name
val age = user.age
var userInfo = "name:${user.name},  age:$age"
//输出结果:name:tutu, age:23

3). lambda

一开始觉得 lambda 很高级完全看不懂,其实很简单的就是把接口名、方法名和参数类型省掉不写再加个->罢了,明白这点了很好理解。

// 无参数无返回值
Thread(Runnable {
    sleep(1000)
}).start()
// 单参数不带返回值
view.setOnClickListener { v ->
    Log.e("tag", "${v.tag}")
}
// 多参数带返回值
view.setOnKeyListener(View.OnKeyListener { v, keyCode, event ->
    Log.e("tag", "keyCode$keyCode, ${event.keyCode}")
    if (event.keyCode == KeyEvent.KEYCODE_BACK)
        return@OnKeyListener true
    false
})

新面孔

  • 1). 延迟加载
  • 2). 流程控制

内容上一篇写过参考 Android Kotlin学习笔记,不重复介绍

空判断

Kotlin 的空安全设计对于声明可为空的参数,在使用时要进行空判断处理,有两种处理方式,字段后加 !! 像 Java 一样抛出空异常,另一种字段后加?可不做处理返回值为 null 或配合 ?: 做空判断处理

//类型后面加?表示可为空
var age: String? = "23" 
//抛出空指针异常
val ages = age!!.toInt()
//不做处理返回 null
val ages1 = age?.toInt()
//age为空返回-1
val ages2 = age?.toInt() ?: -1

更多空处理NullPointException 利器 Kotlin 可选型

注意事项

内部类和参数默认为 public,而在 Java 中为 private
类默认为不可继承(final),想要可被继承要声明为 open 或 abstract
取消了 static 关键字,静态方法和参数统一写在 companion object 块
internal 模块内可见,inner 内部类

以上仅是对使用频率较高的语法总结,学会基本可以阅读 Kotlin 代码,遇到点问题 Google 速查一下,至于智能转换、类型推导之类的不用说使用后喜欢自然就会了。当然这只是 kotlin 的基本语法,方便 Java 快速熟悉 kotlin,深入学习还请阅读相关资料。

相关链接

后记

为了方便收集优秀 Kotlin 文章新建了个专题,有兴趣的欢迎投稿优秀内容
http://www.jianshu.com/c/3c442ef98c83

转载请注明出处:http://www.jianshu.com/u/4025214b6abd

文章目录
  1. 1. 为什么使用Kotlin
  2. 2. 修改说明
  3. 3. Kotlin 基本语法
  4. 4. 万能的冒号
  5. 5. 我是谁的@
  6. 6. 偷懒的方法
  7. 7. 新面孔
  8. 8. 空判断
  9. 9. 注意事项
  10. 10. 相关链接
  11. 11. 后记
|