lambda 的语法
{x: Int, y: Int -> x + y}
即,花括号包围着参数和函数体
如果函数的最后一个参数是lambda,调用时可以将其放在圆括号外。
如果函数的唯一一个参数是lambda,调用时可以省略圆括号。
如果lambda的参数类型可以被推导出来,可以不用显示地指定。
如果lambda只有一个参数,可简化为 it。
val max = people.maxBy({ p: Person -> p.age })
val max = people.maxBy() { p: Person -> p.age }
val max = people.maxBy { p: Person -> p.age }
val max = people.maxBy { p -> p.age }
val max = people.maxBy { it.age }
在作用域中访问变量
默认情况下,局部变量的生命期被限制在声明这个变量的函数中。但如果它被lambda捕捉了,使用这个变量的代码可以被存储并稍后再执行。
如下面的 buttonClickCount 就被存储起来,点击时再执行。
fun Button.setListener() {
var buttonClickCount = 0
this.clickListener = object : ClickListener{
override fun onClick() {
// onClick 捕捉了 var 变量(非 final 变量)
buttonClickCount++
println("you click me $buttonClickCount Time!")
}
}
}
成员引用
::成员
如 Person::age
,会创建一个调用 age 变量的函数值。
// lambda表达式
people.filter { it.age > 0 }
// 匿名普通函数
people.filter(fun(it): Boolean { return it.age > 0 })
// 匿名表达式函数
people.filter(fun(it) = it.age > 0)
// 顶级函数引用
fun judgeAge(it: Person) = it.age > 0
people.filter(::judgeAge)
// 扩展函数引用
fun Person.isAdult() = age >= 21
val predicate = Person::isAdult
people.filter(predicate)
people.filter{it.isAdult()}
// 构造函数引用
val createPerson = ::Person
val p = createPerson("gdeer", 23)
// lambda表达式
people.maxBy { it.age }
// 成员变量引用
people.maxBy(Person::age)
// 顶层变量引用,编译不通过,会报错
// Unsupported [References to variables aren't supported yet]
val judgeAge2 = { person: Person -> person.age > 0 }
val judgeAge3 = fun(person: Person) = person.age > 0
people.filter(::judgeAge2)
people.filter(::judgeAge3)
当 lambda 委托给一个接受多个参数的函数时:
// 两个是等价的
val action = { person: Person, message: String -> sendEmail(person, message) }
val action1 = ::sendEmail