Android 之 kotlin 语言学习笔记一
参考官方文档:https://developer.android.google.cn/kotlin/learn?hl=zh-cn
1、变量声明
Kotlin 使用两个不同的关键字(即 val 和 var)来声明变量。
- val 用于值从不更改的变量。使用 val 声明的变量无法重新赋值。
- var 用于值可以更改的变量。
// 可变变量var count: Int = 10count = 15// 不可变变量val name = "kotlin"name = "java" // 报错
2、类型推断
- Kotlin 是一种静态类型的语言。类型将在编译时解析且从不改变。
val languageName= "kotlin"val upperCaseName = languageName.toUpperCase()// Fails to compilelanguageName.inc()
- toUpperCase() 是一个只能对 String 类型的变量调用的函数。由于 Kotlin 编译器已将 languageName 推断为 String,因此可以安全地调用 toUpperCase()。不过,inc() 是一个 Int 运算符函数,因此无法对 String 调用它。利用 Kotlin 的类型推断,既能确保代码简洁,又能确保类型安全。
3、Null 安全
- Kotlin 提供了严格的可为 null 性规则,可在您的整个应用中维护类型安全。在 Kotlin 中,默认情况下,对对象的引用不能包含 null 值。如需为变量赋 null 值,必须通过将变量类型以问号 ? 为后缀,声明变量为可 null 的类型。
// name 的类型为 String,不可为 null,会编译错误val name: String = null// 若要赋 null 值,需加 ? 符号val name: String? = null
4、条件语句
- Kotlin 提供了几种实现条件逻辑的机制,其中最常见的是 if-else 语句。如果 if 关键字后面括在圆括号内的表达式求值为 true,则会执行该分支中的代码(即,紧跟在后面的括在大括号内的代码)。否则,会执行 else 分支中的代码。
if (count == 42) {println("I have the answer.")} else {println("The answer eludes me.")}
- 您可以使用 else if 表示多个条件。这样,您就可以在单个条件语句中表示更精细、更复杂的逻辑。
if (count == 42) {println("I have the answer.")} else if (count > 35) {println("The answer is close.")} else {println("The answer eludes me.")}
- 为了避免重复代码,Kotlin 提供了条件表达式。每个条件分支都隐式地返回其最后一行的表达式的结果,因此无需使用 return 关键字
val answerString: String = if (count == 42) {"I have the answer."} else if (count > 35) {"The answer is close."} else {"The answer eludes me."}println(answerString)
- 随着条件语句的复杂性不断增加,您可以考虑将 if-else 表达式替换为 when 表达式。when 表达式中每个分支都由一个条件、一个箭头 (->) 和一个结果来表示。如果箭头左侧的条件求值为 true,则会返回右侧的表达式结果。
val answerString = when {count == 42 -> "I have the answer."count > 35 -> "The answer is close."else -> "The answer eludes me."}
- Kotlin 的条件语句有一项强大的功能,即智能类型转换。您不必使用安全调用运算符或非 null 断言运算符来处理可为 null 的值,而可以使用条件语句来检查变量是否包含对 null 值的引用。
val languageName: String? = nullif (languageName != null) {// No need to write languageName?.toUpperCase()println(languageName.toUpperCase())}
5、函数
- 使用 fun 关键字声明函数,后跟函数名称,接着在括号内定义函数的输入类型(如果有),最后使用冒号(:)跟着返回值的类型。在声明函数时,可以指定任意数量的参数及其类型。
fun getName(type: Int): String {// 函数体内容}
(1)简化函数声明
- 函数返回单个表达式的结果时,可以通过直接返回函数中包含的 if-else 表达式的结果来跳过声明局部变量。
fun generateAnswerString(countThreshold: Int): String {return if (count > countThreshold) {"I have the answer."} else {"The answer eludes me."}}
- 还可以将 return 关键字替换为赋值运算符。
fun generateAnswerString(countThreshold: Int): String = if (count > countThreshold) {"I have the answer"} else {"The answer eludes me"}
(2)匿名函数
- 并非每个函数都需要一个名称。某些函数通过输入和输出更直接地进行标识。这些函数称为“匿名函数”。可以保留对某个匿名函数的引用,以便日后使用此引用来调用该匿名函数。与其他引用类型一样,也可以在应用中传递引用。必须像调用命名函数一样调用该函数。
val stringLengthFunc: (String) -> Int = { input ->input.length}val stringLength: Int = stringLengthFunc("Android")
(3)高阶函数
- 一个函数可以将另一个函数当作参数。将其他函数用作参数的函数称为“高阶函数”。此模式对组件之间的通信(其方式与在 Java 中使用回调接口相同)很有用。
fun stringMapper(str: String, mapper: (String) -> Int): Int {// Invoke functionreturn mapper(str)}
- 如果匿名函数是在某个函数上定义的最后一个参数,则可以在用于调用该函数的圆括号之外传递它。
stringMapper("Android") { input ->input.length}
6、类
使用 class 关键字可以定义类。
(1)属性
- 类使用属性来表示状态。属性是类级变量,可以包含 getter、setter 和后备字段。
class Car {val wheels = listOf<Wheel>()}
- 调用类默认构造函数可以获取类的实例,通过实例可以访问它的任何可访问属性。
val car = Car() // construct a Carval wheels = car.wheels // retrieve the wheels value from the Car
- 可以定义一个自定义构造函数,用来指定如何初始化类属性。
class Car(val wheels: List<Wheel>)
(2)类函数和封装
- 类使用函数对行为建模。函数可以修改状态,从而实现只公开希望公开的数据。这种访问控制机制称为“封装”。
class Car(val wheels: List<Wheel>) {private val doorLock: DoorLock = ...fun unlockDoor(key: Key): Boolean {// Return true if key is valid for door lock, false otherwise}}
- 如果希望自定义属性的引用方式,则可以提供自定义的 getter 和 setter。例如,如果希望公开属性的 getter 而限制访问其 setter,则可以将该 setter 指定为 private:
class Car(val wheels: List<Wheel>) {private val doorLock: DoorLock = ...var gallonsOfFuelInTank: Int = 15private setfun unlockDoor(key: Key): Boolean {// Return true if key is valid for door lock, false otherwise}}
7、互操作性
- Kotlin 最重要的功能之一就是它与 Java 之间流畅的互操作性。由于 Kotlin 代码可编译为 JVM 字节码,因此 Kotlin 代码可直接调用 Java 代码,反之亦然。这意味着,可以直接从 Kotlin 利用现有的 Java 库。此外,绝大多数 Android API 都是用 Java 编写的,因此可以直接从 Kotlin 调用它们。