Kotlin 小记-1

255 阅读2分钟

定义只读局部变量使用关键字 val 定义。只能为其赋值一次。相当于java中的final

fun main() {
    val a: Int = 1  // 立即赋值
    val b = 2   // 自动推断出 `Int` 类型
    val c: Int  // 如果没有初始值类型不能省略
    c = 3       // 明确赋值
    println("a = $a, b = $b, c = $c")
}

kotlin 中如果要声明类型 ,是放到变量的后面的 ,就连返回值也是这样的

当某个变量的值可以为 null 的时候,必须在声明处的类型后添加 ? 来标识该引用可为空。

fun parseInt(str: String): Int? {
    // ……
}

fun printProduct(arg1: String, arg2: String) {
    val x = parseInt(arg1)
    val y = parseInt(arg2)
    
    // 直接使用 `x * y` 会导致编译错误,因为它们可能为 null
    if (x != null && y != null) {
        // 在空检测后,x 与 y 会自动转换为非空值(non-nullable)
        println(x * y)
    }
    else {
        println("'$arg1' or '$arg2' is not a number")
    }    
}

when 表达式

// 这个函数可以直接返回值为"=" 
fun describe(obj: Any): String =
    when (obj) {
        1          -> "One"
        "Hello"    -> "Greeting"
        is Long    -> "Long"
        !is String -> "Not a string"
        else       -> "Unknown"
    }

使用区间(range)

使用 in 运算符来检测某个数字是否在指定区间内:

val x = 10
val y = 9
if (x in 1..y+1) {
    println("fits in range")
}

延时初始化属性 惰性加载属性

延时初始化

延时初始化属性要求:
1 不能是可空类型; 
2 只能使用为var声明; 
3 lateinit关键字应该放在var之前。

// 员工类
class Employee {
    ...
    lateinit var dept: Department // 所在部门属性 ①
} 
// 部门类
class Department {
    var no: Int = 0 // 部门编号属性
    var name: String = "" // 部门名称属性
} 
fun main(args: Array<String>) {
    val emp = Employee()
    ...
    emp.dept = Department()
    println(emp.dept)
}

惰性加载属性

惰性加载属性与延迟初始化属性类似,
只有第一次访问该属性时才进行初始化
不同的是惰性加载属性使用的lazy函数声明委托属性,
而延迟初始化属性lateinit关键字修饰属性。
还有惰性加载属性必须是val的,
而延迟初始化属性必须是var的。

val fullName: String by lazy { 
        firstName + "." + lastName
} 

lazy不是关键字, 而是函数。
lazy函数后面跟着的是尾随Lambda表达式。

try catch 可以直接使用最后一行的代码作为返回值(基本可以认为一个大括号内都可以做返回值)

fun test() {
    val result = try {
        count()
    } catch (e: ArithmeticException) {
        throw IllegalStateException(e)
    }

    // 使用 result
}

单表达式函数

fun theAnswer() = 42

等价于

fun theAnswer(): Int {
    return 42
}

对一个对象实例调用多个方法 (with)

class Turtle {
    fun penDown()
    fun penUp()
    fun turn(degrees: Double)
    fun forward(pixels: Double)
}

val myTurtle = Turtle()
with(myTurtle) { // 画一个 100 像素的正方形
    penDown()
    for(i in 1..4) {
        forward(100.0)
        turn(90.0)
    }
    penUp()
}

使用可空布尔 ,其他的数据类型也可以这么搞

val b: Boolean? = ……
if (b == true) {
    ……
} else {
    // `b` 是 false 或者 null
}

交换两个变量 (有点搞不懂,后面再看下)

var a = 1
var b = 2
a = b.also { b = a }