最近在Kotlin代码中,我经常看到这样的写法:
interface Person {
fun saySomething()
}
class Adult: Person {
var name = ""
override fun saySomething() {
println("Hello world!")
}
fun weirdSay(block: Person.() -> Unit) {
println("包装一下")
this.block()
}
private fun sayMore() {
println("私有办法")
}
fun answer(question: String) {
println("$question 的答案")
}
}
fun main() {
val adult = Adult()
adult.weirdSay {
saySomething()
// sayMore() 无法找到私有办法
// answer("问题") 无法找到
}
}
输出为
包装一下
Hello world!
注意看main函数,这里调用了adult的weirdSay,传入一个lambda表达式,传入的居然是adult自己的saySomething,那是因为block: Person.() -> Unit
语法
() -> Unit
是Kotlin界说不接纳任何参数并且不回来任何东西的函数的方式。
并且有一种办法能够指定该函数将在何处被调用,因此有了Person.()
部分。
一个参数类型为 Person.() -> Unit
的 Lambda 表达式,它能够拜访和修正 Person
类型的特点和办法,具体意义是:为“给我一个在Person上调用的块。它必须不接纳任何参数,并且不回来任何东西。”
显然,这是一种界说即时扩展函数的方式。这允许你界说在类内部运行可是从类外部界说的函数。
也就是说,当咱们需求在事务中用到某个类内部的办法时,咱们能够给这个类内部添加一个类似于 fun weirdSay(block: Person.() -> Unit) {
的办法,对需求调用的办法进行相应的处理,然后在外面直接调用weirdSay就行了,一起,在外部也能够拜访或许修正特点
class Person(var name: String) {
fun say() {
println("My name is $name")
}
fun weirdSay(block: Person.() -> Unit) {
println("包装一下")
block()
}
}
fun main() {
val person = Person("Tom")
person.weirdSay {
name = "Jerry"
say()
}
}
输出为
包装一下
My name is Jerry
这姿态,大都情况下,就能够在这一扩展函数中自在的像在person类中调用自己一样,比如
interface Person {
fun saySomething()
fun sayMore()
}
class Adult: Person {
override fun saySomething() {
println("Hello world!")
}
fun weirdSay(block: Person.() -> Unit) {
println("包装一下")
this.block()
}
override fun sayMore() {
println("sayMore")
}
}
fun main() {
val adult = Adult()
adult.weirdSay {
saySomething()
sayMore()
}
}
添加一个sayMore办法,也能够持续调用,weirdSay{}内部就像person的内部一样(除了private不能拜访)
学习到了小技巧,就赶紧用到项目中吧!