Skip to Content
Kotlin惯用法

惯用法

延迟属性

延迟属性 ( Lazy property ) 仅在变量被初次调用时被计算和赋值,这个过程只会被执行一次

val expensiveData: String by lazy { println("Expensive data initialing") println("Loading.....") "This is expensiveData" } println(expensiveData) println(expensiveData)

扩展函数

扩展函数能够被定义在类外,从而扩展类的功能,但扩展函数不能访问私有成员,不能被继承和重写

class Student(val name: String) fun Student.sayName() { println(name) } fun main() { Student("Cherry").sayName() }

创建单例对象

单例对象将初次访问时被初始化,且在整个程序的生命周期内只存在这一个实例

object Resource { val name = "Name" fun getName(): String { return name } }

实例化抽象类

abstract class Person(val name: String, val age: Int) { abstract fun sayName() } fun main() { val myObject = object : Person("Cherry", 20) { // 使用object定义了一个匿名类 override fun sayName() { TODO("Not yet implemented") } } }

获取可空集合中的首个元素

val values = listOf(1, 2, 3, 4, 5, 6) val negativeValues = values.filter { it < 0 } println(values.firstOrNull()) // 1 println(negativeValues.firstOrNull()) // null // .firstOrNull()将在首个元素为null时返回空

非空时调用(let)

let本质上是一个作用域函数,在指定的作用域内的函数

val value:Int? = 1 value?.let { println("Value is not null") } // 当value不为空时调用
class Student(val name: String) fun main() { Student("Cherry").let { println("Student's name is ${it.name}") } } // 同时能够执行Lambda

除此之外的作用域函数(内联函数)还有:runwithapplyalso

try..catch异常处理

fun divide(a: Int, b: Int) = try { a / b } catch (e: ArithmeticException) { e.printStackTrace() 0 }

返回Unit的方法的构造者风格用法

fun arrayOfMinusOne(size: Int): Array<Int> { return arrayOf(size).apply { fill(-1) } // 使用了apply函数从而简化代码 }

Java 7的try-with-resource

Kotlin中并不含有IO流,此处调用的包为java.nio(新IO流)

val stream = Files.newInputStream(Paths.get("/home/cherry/TempDir/test.cpp")) stream.buffered().reader().use { reader -> println(reader.readText()) } // 实现了Closable接口的对象都能够调用.use{},无论是否发生异常,use{}均会自动关闭其调用者 // use中发生的异常会被抛出,不会被隐藏

需要泛型类型信息的泛型函数

fun <T> printElement(element: T) { println(element) } // <T>会被自动推导

可空布尔值

val b: Boolean? = null if (b == true) { println("B is true") } else { println("B is false of null") }

交换两个变量

var a = "A" var b = "B" a = b.also { b = a } // 在Lambda表达式中,b被赋予a的值,also返回b本身,a被赋予b的值

标记为未完成的代码(TODO)

fun notImplementedFunction() { TODO() // TODO始终抛出异常,其返回值为Nothing }

Nothing

Nothing与Java中的void不同,表示确实没有值,Nothing不具有值,且不能被实例化,但Nothing是所有类型的子类型,Nothing能够:

作为函数的返回值类型,明确这是一个「不会返回的函数」

fun throwException(): Nothing { throw RuntimeException("This is a exception") // 抛出异常的函数始终不会返回 } // 还有无限循环,但是使用很少

作为泛型变量通用的、空白的临时填充

val emptyList: List<Nothing> = listOf() var intList: List<Int> = emptyList

语法层面的完整化

fun sayMyName(first: String, second: String) { val name = if (first == "Walter" && second == "White") { "Heisenberg" } else { return // 由于Nothing是任意类型的子类型,可以直接用与String类型的name(语法层面) } println(name) }
Last updated on