最近在学NDK相关的知识,本来Kotlin的学习,是被计划在后面的,因为暂时项目中也没有用到,担心学了估计很快就忘记。在某次写小demo代码做测试的时候,就在想,都是简单的语法,如果拿来做Kotlin的练手也是蛮不错的。
另外就是,现在Google官网上的代码实例,都贴上Kotlin实例了,github上新的开源框架,也很多用Kotlin,看来google是认真的了,Kotlin必学不可了。
刚好遇到国庆,除去出去玩还剩2、3天在家,那就立马把Kotlin学起来
[TOC]
学习流程
有了Java的基础,所以,主要就是学Kotlin的一些语法,明白和Java之间的差异,并通过一个完整的Android实践项目熟悉Kotlin在Android上的应用。
参考书籍
《Kotlin官方参考文档》
Kotlin官方的文档,比较详细介绍了Kotlin的各种语法,不过我只是把开始章节的基础语法、习惯用法、编码规范学好,接下来的章节,挑着看,比如对象的某个章节就详细看了一下。
《Kotlin实战》
在查某个知识点看到的书籍,介绍得很详细,入门比官方文档好,可以结合查阅。
《kotlin-for-android-developers》
介绍怎样用Kotlin编写一个Android简单项目,基本把各个知识点都介绍一篇,有点像N年前入门学Android看郭神的第一行代码的感觉。接下来的学习,主要是靠这本书,结合源码以及上面的两本参考书,外加google搜索不理解的知识点。
Kotlin基础语法
注释
1 | // 这是一个行注释 |
Kotlin添加注释,为什么不会自动生成一些参数
-
看官方的说明,就是禁止用Java那种定义参数,然后后面补充说明的注释,而是将参数结合到文档的过程中结合上下文描述来说明参数的作用
-
官方不建议使用,如果还是想创建文件自动生成模板注释,或者想和Java一样生成方法模板,可以参考该文件。
变量
var
:可变变量val
:不可变变量,尽可能地使用不可变变量
-
总结
var
、val
声明的变量分为三种类型:顶层属性、类属性和局部变量;var
属性可以生成 getter 和 setter,是可变的(mutable),val
属性只有 getter,是只读的(read-only,注意不是 immutable);- 局部变量只是一个普通变量,不会有 getter 和 setter,它的
val
等价于 Java 的final
,在编译时做检查。 const
只能修饰没有自定义 getter 的val
属性,而且它的值必须在编译时确定。
基本数据类型
判断两个数值是否相等(==
),判断两个数值在内存中的地址是否相等(===
)
-
对官方的基本类型自动装箱详细介绍,并演示怎样反编译成Java字节码进行理解
-
参考其中的装箱与拆箱
注意点
- 数字类型中不会自动转型
- 字符(Char)不能直接作为一个数字来处理
- 声明一个变量可以不写明具体的类型,会自动推断。
字符串模板
模板表达式以美元符( $
)开头,由一个名字构成或者用花括号括起来的任意表达式
1 | fun main(args: Array<String>) { |
可空性
Kotlin和Java的类型系统之间,最重要的一条区别就是,Kotlin对可空类型的显式支持。如果不做特别声明,在Kotlin中,该对象是不允许为null
的,即默认都是非空的。如果想让对象可能为空,需要在类型名称后面加上?
来标记它。
1 | var 变量名:变量类型? = null |
声明一个变量,可能为空,那么,在使用的时候,就要进行空判断了,在Java中,经常要写if xxx != null
的判断,非常麻烦,尤其是多层调用,使用起来特别繁琐。
在Kotlin中,就可以用安全调用运算符?.
,不为空则调用,空则返回null
。
1 | val a : String? = a?.length() |
为空的话,默认返回null
,如果想代替null的默认值,可以使用Elvis运算符?:
1 | val a : String? = a?.length()?:0 |
安全转换as?
判断被转换的值是不是要转换的类型,不是则抛出异常,通常与Elvis运算符结合使用。
1 | fun equals(o: Any?): Boolean{ |
非空断言!!
1 | a!! |
Unit和Nothing
用途之一
1 | interface Processor<T> { |
函数
1 | // 无返回值,返回类型可以深入 |
使用for循环
1 | fun main(args: Array<String>) { |
When表达式
when
取代了switch操作符,x不只是常量,还可以是表达式。else
作用和default类似,上面都不符合则会执行else
分支
1 | when(x) { |
类
默认任何类都是基础继承自 Any
(与java中的 Object 类似),所有的类默认都是不可继承的(final),所以我们只能继承那些明确声明 open
或者 abstract
的类。
创建类的实例对象,不需要new
关键字。
构造函数
在kotlin中,构造函数可以有一个主构造函数和多个次构造函数,主构造函数为类头的一部分,跟在类名后。
1 | // name就直接被初始化了,可以直接使用了 |
1 | // java的写法,与上面的kotlin作用一样 |
主构造函数中不能有其他代码,如果要进行初始化,那么放在init
代码块中。
执行顺序:主构造函数 —> 初始化块代码 —> 次构造函数
object 和 companion object
被companion object修饰的对象,就像Java中的静态属性或者方法一样,被这个类的所有对象所共享。
operator 运算符重载
在大多数编程语法中,我们预定了+
作为算法运算符,也可以与String值一直使用。但是,算法预算符也就只是应用在基本数据类型,比如,定义一个点数据类Point,如下
1 | data class Point(val x: Int, val y: Int) |
如果想把两个点加在一起,需要分别取点的x、y加上另外一个点的x、y。那么,如果能直接用运算符+
就好了,运算符重载就可以帮你实现。
+
运算符的函数名为plus,那么,就来重载plus方法,如下代码
1 | data class Point(val x: Int, val y: Int) { |
1 | // 上面已经对Point进行重载算术运算符 |
《Kotlin实战》
运算符重载的其他预定,包括重载二元算术运算、重载复合赋值运算、重载一元运算符。重载比较运算符的详细介绍,可以参考该书的第7章
-
如果觉得看书的整一章太长,可以看该文章,就是书中的笔记,也是搜到这篇文章让我找到上面的书,才搞懂operator的作用
-
with
在很多语法中,经常要要同一个对象执行多次操作,如果使用了with
函数,就不需要把对象的名称写出来。基本结构就是with(){}
1 | fun alphabet(): String { |
上面的result对象需要写很多次,使用with
函数就可以减少
1 | fun alphabet(): String { |
使用类型检测及自动类型转换
1 | fun getStringLength(obj: Any): Int? { |
kotlin 委托
-
菜鸟教程的文章,分别介绍了类委托、属性委托、标准委托、可观察属性 Observable
-
个别地方结合Java介绍,方便理解
Kotlin for Android
修改build.gradle支持kotlin
1 | // build.gradle文件 |
1 | // app/build.gradle文件 |
Anko
Anko是一个Kotlin库,可以帮助你更快、更轻松地开发Android应用程序,而且,能让代码清晰易读。
Anko主要由四部分组成,使用的话,可以引用不同的依赖库
- Anko Commons: 最常使用的一个轻量级的库,里面包含用于Intents;
Dialogs and toasts;
Logging;
Resources and dimensions; - Anko Layouts: 能够通过快速且安全类型去编写Android动态布局的依赖库。
- Anko SQLite: 查询DSL(领域专用语言)和解析Android SQLite数据库
- Anko Coroutines: 基于kotlinx.coroutines的工具类库
build.gradle
1 | dependencies { |
参考资料
-
简单得介绍怎样使用Anko Layouts以及使用Android Studio插件Anko support预览布局
-
简单介绍一下Anko库的使用
-
在使用Anko Coroutine之前,需要对Coroutine(协程)有一点了解,可以参考该系列文章