Kotlin学习之旅(D1)-学习计划&基本语法

2017年的Google I/O 开发者大会

Kotlin正式成为了Android的官方支持语言

2018年的国庆小长假最后一天

BlueLzy正式开始Kotlin学习之旅

学习计划

学什么?

今天是Kotlin学习之旅的第一天,这次Kotlin之旅的行程计划是21天

目的:

每天只要花30分钟-1个小时,坚持21天,掌握Kotlin开发Android项目所需知识

包括:

  • 基础语法(2D)

  • 高级语法(3D)

  • Kotlin Idioms(2D)

  • From Java to Kotlin(2D)

  • Kotlin Android Extensions(2D)

  • Unit Test with Kotlin(2D)

  • 使用Kotlin完成一个Android小项目(7D)

  • 总结(1D)

不包括:

  • Kotlin对比Java的好处,为什么要学习Kotlin
  • 怎么安装Android Studio / IDEA
  • 怎么加入Kotlin依赖

需要的前置技能:任意一种编程语言基础,基本数据类型,操作符等基础知识已掌握即可

怎么学?

1.根据20/80法则,我们不需要掌握Kotlin所有的知识点,只需要掌握20%最常用就足以应付80%的场景了

2.学习金字塔法则,被动学习和主动学习的知识留存率是差很多的:

3391dd8c4e9aac9e.jpg

尽量做创造性(输出)的事情,例如写总结,做笔记,敲代码,甚至内部分享,写成教程等

3.Learning By Doing法则,整个Kotlin学习之旅主要分为两个部分

  • 理论部分:主要是参考kotlinlang.org,并配上Sample Code

  • 实践部分:使用Kotlin编写一个Todo项目,选择这个项目的原因是:无网络请求,方便编写Unit Test,项目结构较为简单,7天即可完成

编程最重要就是动手敲,最终要的是能运行的程序,因此建议大家都跟着动手敲一遍

基本语法(Part Ⅰ)

变量

在Java里面,定义 常量 的写法是加上final关键字

而在Kotlin里面,定义常量的关键字是:val

1
2
val a: Int = 0 // 相当于java里面的 private static final int a = 0;
val b = 2 // 省略Int类型,在kotlin中也是允许的,Kotlin可以自动推断变量的类型

那么要定义 变量 要怎么写呢?

通过关键字:var

1
2
var c = 0 // 省略Int类型
c += 1

Tips:在kotlin中,我们可以省略每行代码最后的分号 ‘ ; ‘

延迟初始化 - Late-Initialized:

由于在Kotlin里面变量是non-null的,但是有些时候我们需要在执行完某个操作后再赋值,那么就需要用到延迟初始化,通过 lateinit 关键字来实现

1
2
3
4
5
6
7
8
9
10
class Address {
var name: String = ...
var street: String = ...
lateinit var city = ...
}

// 通过isInitialized来检查变量是否已经被初始化
if (address::city.isInitialized) {
println(address.city)
}

函数

通过 fun 关键字来定义函数,例如:

1
2
3
fun nothing(){
println("i am an empty function")
}

有参函数:

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

这里我们传入a,b两个Int参数,返回值也是Int类型

a: Int - 参数名: 参数类型

fun(): Int - 函数: 函数返回值类型

更简洁的写法:

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

通过 ‘’=’’ 来表示 return 语句,注意:返回值只有一条表达式的时候才适用

参数有默认值的函数:

1
fun sum(a: Int = 1, b: Int = 1) {...}

此时a,b的默认值都是1

注释

1
2
3
4
// 单行注释

/* 这是一个多行注释
这是一个多行注释 */

String字符串模板

使用 $var_name 来表示变量的值

1
2
3
4
5
6
7
var a = 1
val s1 = "a is $a"

a = 2
val s2 = "${s1.replace("is","was")}, but now is $a"

println(s2)

这段代码的输出结果为:

1
a was 1, but now is 2

s1 的初始值为: a is 1,然后通过.replace()函数,把 is 替换为 was ,此时 s1变成了 a was 1

条件语句

条件语句的判断通常是 if 语句

1
2
3
4
5
6
7
fun maxOf(a: Int, b: Int): Int {
if (a > b) {
return a
} else {
return b
}
}

更简洁的写法,记得上面我们说过的 “=” 来替换 return 吗:

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

这里其实使用了if 不加括号只执行一行的特性,常规写法应该是这样的:

1
2
3
4
5
fun maxOf(a: Int, b: Int) = if (a > b){
a
} else {
b
}

但是这样实在是太难看了,所以就省略了大括号,把返回结果直接写在一行代码里

可空类型和null检查

Kotlin具有空安全(null safety)特性,但是有时候我们就是想要返回null,该怎么办呢?

当str不存在整数时返回null:

1
2
3
fun parseInt(str: String): Int? {
// ...
}

官方文档给出的Sample:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
fun parseInt(str: String): Int? {
return str.toIntOrNull()
}

fun printProduct(arg1: String, arg2: String) {
val x = parseInt(arg1)
val y = parseInt(arg2)

// ...
if (x == null) {
println("Wrong number format in arg1: '$arg1'")
return
}
if (y == null) {
println("Wrong number format in arg2: '$arg2'")
return
}

// x and y are automatically cast to non-nullable after null check
println(x * y)
}

fun main(args: Array<String>) {
printProduct("6", "7")
printProduct("a", "7")
printProduct("99", "b")
}

输出结果为:

1
2
3
42
Wrong number format in arg1: 'a'
Wrong number format in arg2: 'b'

分析一下:

printProduct(“6”, “7”):x,y都能转成Int类型,因此x,y都不是null,println(x * y) = 6 x 7 = 42

printProduct(“a”, “7”):x为”a”不能转成Int,因此x为null,执行

1
println("Wrong number format in arg1: '$arg1'")

printProduct(“99”, “b”) :同上

说明在fun或者var 加上 “?” 就表示该类型可以为null,后面就需要进行是否为null的判断

类型检查与强制类型转换

Kotlin中,“is” 是类型检查的关键字

1
2
3
4
5
6
7
8
9
fun getStringLength(obj: Any): Int? {
if (obj is String) {
// `obj` is automatically cast to `String` in this branch
return obj.length
}

// `obj` is still of type `Any` outside of the type-checked branch
return null
}

在这里,执行 obj.length 的时候,obj 会强制类型转换为 String

又或者可以这样写

1
2
3
4
5
6
fun getStringLength(obj: Any): Int? {
if (obj !is String) return null

// `obj` is automatically cast to `String` in this branch
return obj.length
}

这两段代码的意思都是一样的,通过 is 或者 !is 进行类型检查

使用 “as?” 进行“安全的”类型转换

例如: null 不能转换为String,因为String 是不可为null的,那么这个时候我们可以用这种方式:

1
val x: String? = y as? String

当y为null的时候,结果会返回null,而不会抛出异常

总结

今天是Kotlin学习之旅的第一天,主要学习了Kotlin的基础语法,包括:

  • 变量
  • 函数
  • String字符串模板
  • 条件语句
  • 可空类型和null检查
  • 类型检查与强制类型转换

明天会学习剩下的基础语法,包括:

  • for循环和while循环
  • when表达式
  • 遍历集合

面向对象编程打算在高级语法里面学习,因为这一块的知识点比较多,需要花的时间精力也会多一些。

好了,那么Day 1 的学习到此就结束啦。


本文结束啦感谢您的阅读