惯用法
延迟属性
延迟属性 ( 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
除此之外的作用域函数(内联函数)还有:run
、with
、apply
、also
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