关于 Kotlin 的安装,Android studio 3.0及以上自带,其他的可以通过搜索插件 Kotlin 来进行安装。下面来说说有关 Kotlin 的语法。
以下是本人的学习笔记,入有任何不妥之处,随时欢迎拍砖指正。
谢谢 ^_^
1. Kotlin Android 扩展
Kotlin 插件自带有安卓扩展,因此不需要再单独安装额外插件。
我们直接 new Kotlin Activity 后出现提示让配置 Kotlin

通过点击来自动导入 Kotlin 所需要的配置

实际上在项目的 Gradle上多了一行

项目 module 的 build.gradle 中多了

apply 多了

以上都是自动生成的
然后我们需要在项目 module 的 build.gradle 文件中添加以下代码
1
| apply plugin: 'kotlin-android-extensions'
|
这样我们就可以用简写了,比如在 XML 中定义一个 TextView
1 2 3 4 5
| <TextView android:id="@+id/hello" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello World!"/>
|
我这里 ID 设置为『hello』那么我们在 Activity 中的代码就变成了
1 2 3 4 5 6 7 8
| class KotlinActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_kotlin) hello.text = "你是不是傻" } }
|
这样直接通过 hello.text 来设置内容,而不是原来长长的
1
| findView(R.id.textView) as TextView
|
该插件相当于把 XML 中的控件『id』作为 Activity 的额外属性来使用。
简洁了很多~~
2. 定义函数
Kotlin 中所有的函数直接通过 fun 来声明。
1 2 3 4 5
| fun sum(a: Int , b: Int) : Int{ return a + b } fun sum(a: Int, b: Int) = a + b
|
上面两种方式都可以通过以下代码来调用。
1 2
| // 输出如下: I/System.out: 8
|
3. 定义局部变量
1 2 3 4 5
| val a: Int = 1 // 立即初始化 val b = 2 // 推导出Int型 val c: Int // 当没有初始化值时必须声明类型 c = 3 // 赋值 println("a = $a, b = $b, c = $c")
|
1 2 3
| var x = 5 // 推导出Int类型 x += 1 println(" x = $x")
|
1 2
| // 输出如下: I/System.out: x = 6
|
4. 注释
与 Java 和 JavaScript 一样,Kotlin 支持单行注释和块注释。
5. 使用字符串模板
1 2 3 4 5 6 7 8 9 10
| var a = 1 // 使用变量名作为模板: val s1 = "a is $a" println(s1) a = 2 // 使用表达式作为模板: val s2 = "${s1.replace("is", "was")}, but now is $a" println(s2) println(s1)
|
1 2 3 4
| // 输出如下: I/System.out: a is 1 I/System.out: a was 1, but now is 2 I/System.out: a is 1
|
我发现在 val s2 中通过 replace 修改了 s1 的值,但是在最后的输出 s1 时,s1 的值并没有改变。
通过进入 replac 方法得知使用该方法后的字符串会重新生成新的字符串,并不改变原值~O(∩_∩)O哈哈~ 一看就是我 Java 基础没学好~
附图:

6. 使用条件表达式
1 2 3 4 5 6 7
| fun maxOf(a: Int, b: Int): Int { if (a > b) { return a } else { return b } }
|
1
| fun maxOf(a: Int, b: Int) = if (a > b) a else b
|
1 2
| println("我今年${maxOf(0, 18)}岁了.") hello.text = "我今年${maxOf(0, 18)}岁了."
|
1 2
| // 输出如下: I/System.out: 我今年18岁了.
|

以上两种方式都可以表达。
7. 使用可空变量以及空值检查
开发中最常见的错误应该就是NullPointerException
了,那么 Kotlin 是怎么解决这个问题的呢?
7.1 可空类型和非空类型
Kotlin 中用 ? 来表示该变量是否可以为空。下面看实例

当我们没有明确 String 可以为空的情况下,当 String 赋予null 时,会报错,导致无法运行。
前者我们可以直接调用
1 2 3
| val l2 = a2.length 但是后者 val l3 = a3.length
|
我们不可以直接调用,因为 a3 可能为空,这里我们就要用到条件表达式了
7.2 在条件中检查 null
1 2 3 4
| val l3 = if (a3 != null) a3.length else -1 // 输出如下: I/System.out: 3
|
或者
1 2 3 4
| if (a3 != null && a3.isNotEmpty()) println("Stirng of length ${a3.length}") else println("Empty string")
|
1 2
| // 输出如下: I/System.out: Stirng of length 3
|
7.3 安全调用
使用安全操作符,?.
如果 a3
不为空则返回长度,否则返回空。
这个表达式的的类型是Int?
安全调用在链式调用是是很有用的。比如,如果 Bob 是一个雇员可能分配部门(也可能不分配),如果我们想获取 Bob 的部门名作为名字的前缀,就可以这样做:
1
| bob?.department?.head?.name
|
这样的调用链在任何一个属性为空都会返回空。
7.4 Elvis 操作符
使用 Elvis 操作符,?:
如果 ?:
左边表达式不为空则返回,否则返回右边的表达式。注意右边的表达式只有在左边表达式为空才会返回。
7.5 !! 操作符
用 b!! ,这会返回一个非空的 b 或者抛出一个 b 为空的 NPE
val l = b !!.length
7.6 安全转换
普通的转换可能产生 ClassCastException 异常。另一个选择就是使用安全转换,如果不成功就返回空:

1 2 3
| var b = "aaa" val aInt: Int? = b as? Int println(aInt)
|
1 2
| 输出如下: I/System.out: null
|
这样如果 b 是 int 的类型的就输出,不是就返回 null
而不会像以前一样程序 crash 后报 ClassCastException 异常
8. 使用值检查并自动转换
使用 is
操作符检查一个表达式是否是某个类型的实例。如果对不可变的局部变量或属性进行过了类型检查,就没有必要明确转换:
1 2 3
| fun printLength(obj: Any) { println("'$obj' string length is ${getStringLength(obj) ?: "... err, not a string"} ") }
|
1 2 3 4 5 6 7 8 9
| fun getStringLength(obj: Any): Int? { if (obj is String) { // obj 将会在这个分支中自动转换为 String 类型 return obj.length } // obj 在种类检查外仍然是 Any 类型 return null }
|
通过调用:
1 2 3
| printLength("Incomprehensibilities") printLength(1000) printLength(listOf(Any()))
|
1 2 3 4
| 输出如下: I/System.out: 'Incomprehensibilities' string length is 21 I/System.out: '1000' string length is ... err, not a string I/System.out: '[java.lang.Object@72fd5e4]' string length is ... err, not a string
|
当然我们也可以换一种方式来写
1 2 3 4 5 6
| fun getStringLength(obj: Any): Int? { if (obj !is String) return null // obj 将会在这个分支中自动转换为 String 类型 return obj.length }
|
甚至可以这样
1 2 3 4 5 6 7 8
| fun getStringLength(obj: Any): Int? { // obj 将会在&&右边自动转换为 String 类型 if (obj is String && obj.length > 0) { return obj.length } return null }
|
以上代码的输出结果是不变的。
9. 使用循环
1 2 3 4
| val items = listOf("Google", "Apple", "Amazon") for (index in items.indices) { println("item at $index is ${items[index]}") }
|
1 2 3 4
| // 输出如下: I/System.out: item at 0 is Google I/System.out: item at 1 is Apple I/System.out: item at 2 is Amazon
|
10. 使用 while 循环
1 2 3 4 5 6
| val items = listOf("Google", "Apple", "Amazon") var index = 0 while (index < items.size) { println("item at $index is ${items[index]}") index++ }
|
输出结果和 for 循环一样
11. 使用 when 表达式
Kotlin 中的 when 表达式就是类似于 Java 中的 switch 语句
1 2 3 4 5 6 7
| when (obj) { 1 -> "One" "Hello" -> "Greeting" is Long -> "Long" !is String -> "Not a string" else -> "Unknown" }
|
1 2 3 4 5
| println(describe(1)) println(describe("Hello")) println(describe(1000L)) println(describe(2)) println(describe("other"))
|
参数分别使用了『1』,『Hello』,『1000L』,『2』,『other』
分别对应下列的输出。和 switch 语法一模一样,只不过把一些过程给简化了。
1 2 3 4 5 6 7
| // 输出如下: I/System.out: item at 2 is kiwi I/System.out: One I/System.out: Greeting I/System.out: Long I/System.out: Not a string I/System.out: Unknown
|
可能对于第四个有疑惑
1 2 3
| println(describe(2)) !is String -> "Not a string"
|
以上意思是说 2 不是 String 类型的实例,结果为 true 所以输出了 『Not a string』
12. 使用ranges
使用 in 操作符检查数值是否在某个范围内:
1 2 3 4 5
| val x = 10 val y = 9 if (x in 1..y+1) { println("fits in range") }
|
1 2
| // 输出如下: I/System.out: fits in range
|
表达式的意思是说 x 是否在 1 ~ y + 1 的范围内
从定义的 x 和 y 的值来说,显而易见为 true
检查数值是否在范围外:
1 2 3 4 5 6 7 8 9 10 11
| val list = listOf("a", "b", "c") if (-1 !in 0..list.lastIndex) { println("list.lastIndex: ${list.lastIndex}") println("-1 is out of range") } if (list.size !in list.indices) { println("list.indices: ${list.indices}") println("list size is out of valid list indices range too") }
|
1 2 3 4 5
| // 输出如下: I/System.out: list.lastIndex: 2 I/System.out: -1 is out of range I/System.out: list.indices: 0..2 I/System.out: list size is out of valid list indices range too
|
!in
即不属于该范围 -1 不属于0~2,3也不属于0~2
所以他们的println
语句都输出了。
在范围内迭代或者使用步进:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| for (x in 1..5) { println(x) } println("----------------") for (x in 1..10 step 2) { println(x) } println("----------------") for (x in 9 downTo 0 step 3) { println(x) }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| // 输出如下: I/System.out: 1 I/System.out: 2 I/System.out: 3 I/System.out: 4 I/System.out: 5 I/System.out: ---------------- I/System.out: 1 I/System.out: 3 I/System.out: 5 I/System.out: 7 I/System.out: 9 I/System.out: ---------------- I/System.out: 9 I/System.out: 6 I/System.out: 3 I/System.out: 0
|
step
跳跃
downTo
从大到小
看了 Log 日志,聪明的你应该懂了吧~~
13. 使用集合
对一个集合进行迭代:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| val items = listOf("Google", "Apple", "Amazon") for (item in items) { println(item) } println("----------------") when { "tutu_oo" in items -> println("Change The World") "Google" in items -> println("My Dream") } println("----------------") val fruits = listOf("banana", "avocado", "apple", "kiwi") fruits .filter { it.startsWith("a") } .sortedBy { it } .map { it.toUpperCase() } .forEach { println(it) }
|
1 2 3 4 5 6 7 8 9
| I/System.out: Google I/System.out: Apple I/System.out: Amazon I/System.out: ---------------- I/System.out: My Dream I/System.out: ---------------- I/System.out: APPLE I/System.out: AVOCADO I/System.out: ----------------
|
第一个是最普通的循环打印
接下来是 when 表达式,它只会执行一次
如果表达式是这样的
1 2 3 4
| when { "Amazon" in items -> println("Change The World") "Google" in items -> println("My Dream") }
|
1 2 3 4 5 6 7 8 9
| I/System.out: Google I/System.out: Apple I/System.out: Amazon I/System.out: ---------------- I/System.out: Change The World I/System.out: ---------------- I/System.out: APPLE I/System.out: AVOCADO I/System.out: ----------------
|
后面的 Google 即使也在 items 集合里面但是也不会输出『My Dream』
最后就是链式调用了,让我想到了 RxJava ,首先通过 filter 过滤只留下『a』 开头的,然后应该是自然排序,接着通过 map 转换成大写,最后将每一个都输出。
关于我
一只成长中的图图。
感谢
参考自:
https://www.kotlincn.net/docs/tutorials/android-plugin.html
https://huanglizhuo.gitbooks.io/kotlin-in-chinese/content/GettingStarted/Basic-Syntax.html