《极客时间---快速上手Kotlin开发》学习笔记(三)
2019-12-08 本文已影响0人
青_雉
16 ~ 20讲
Scope Functions
Kotlin 里 函数是一等公民,其中有一类特殊的函数,叫做 scope functions , 特指 let, run, also, apply with, 他们存在于kotlin的标准库里。(存在于Standard.kt文件中)
玩法如下:
属性转换
var s = Student("10", "zhangsan")
var teacher = s.let {
teachers[it.teacherId] ?: "teacher not found"
}
println("student ${s.name}'s teacher is $teacher")
对象初始化
var s = Student("1", "zhangsan").also { it.name = "inited by also" }.also { println(it) }
等同与
var s1 = Student("2", "lisi").apply { this.name = "inited by apply" }.apply { println(this) }
with用法
fun main(args: Array<String>) {
var r = with(StringBuilder("hello")) {
append(" teacher!")
toString()
}
println(r)
}
Function Literal with Receiver(带接受者的函数字面量)
在高阶函数中,可以定义函数为另一个函数的输入参数,比如(In) -> Out
在此可以针对输入参数的函数指定一个receiver, 比如:Receiver.(In) -> Out
如下面的例子:
block: StringBuilder.() -> Unit 定义的函数是函数createString的输入参数, receiver是 StringBuilder
这样在函数定义的具体实现时(main方法调用),函数内,都属于StringBuilder的context,这个函数就好像是StringBuilder的拓展函数,可以通过this关键字直接调用StringBuilder里的方法,当然this可以省略。
inline fun createString(block: StringBuilder.() -> Unit): String {
val sb = StringBuilder()
sb.block()
return sb.toString()
}
fun main(args: Array<String>) {
val s = createString { //here we're in the context of a StringBuilder
append(4)
append("hello")
}
println(s)
}
查看Standard.kt文件里的scope functions, 大量使用了function literall with receiver 特性, 比如 with
运算符
fun main(args: Array<String>) {
//in 相当于contain
var name = "zhangsan"
println("ang" in name)
for (i in 1..10 step 4) {
println(i)
}
//对string类型来讲
//== --> java equal
//=== --》 java ==
var z1 = "abc"
var z2 = String(z1.toByteArray())
println("z1 $z1 z2 $z2")
println(z1 == z2)
println(z1 === z2)
}
运算符也可以被重载
fun Any.println() = println(this)
data class Foo(var x: Int, var y:Int)
operator fun Foo.plus(other: Foo): Foo = Foo(x + other.x, y + other.y)
fun main(args: Array<String>) {
var f1 = Foo(1, 2)
var f2 = Foo(3, 4)
var f3 = f1 + f2
f3.println()
}
中缀
- 通过
infix修饰函数 - 有且只有一个入参
- 相当于给某一个类做了一个特殊的扩展函数
fun main(args: Array<String>) {
var name : String? = null
name ifNullAlert "姓名不能为空"
}
infix fun <T> T.ifNullAlert(x: String){
if (this == null) {
throw RuntimeException(x)
}
}
反引号
- 把不合法变成合法
- 这种“合法” 一般不用,用了就是为了不让java代码调用
fun main(args: Array<String>) {
` `()
}
fun ` `(){
println("ddd")
}