lambda是什么
- 首先写一个最普通的方法(method01):
fun method01(name: String): Int {
return name.length
}
- 然后把方法名删了,发现提示方法需要有个方法名
- 然后把这个报错的方法赋值给一个变量 method02 , 发现不报错了
val method02 = fun(name: String): Int {
return name.length
}
思考: method01 和 method02 时一回事吗
- 我们们尝试调用一下这个两个方法,好像直接使用上没有什么差别
fun test() {
method01("hello")
method02("Hello")
}
- 我们看一下编译器对这个两个方法调用的解释,可以发现,method01 提示的是一个普通的方法,但是method02 给出的的是一个 [(String)-> Int ] 这样的表示,其实这就是一个lambda 表达式
3.我们换一种方式调用两个方法,我们会发现,method02可以像一个对象一样调用一个 invoke 方法 ,但是method01 不行
- 但是 给method01前面加两个双冒号 就可以了
Kotlin 中 双冒号操作符 (函数的引用) 表示把一个方法当做一个参数,传递到另一个方法中进行使用,通俗的来讲就是引用一个方法 参考文档
结论: lambda [(String)-> Int ],其实是一个函数类型的对象而已,也是一个匿名函数,与函数名加双冒号是一个东西,可以直接作为函数的参数来直接传递。所以Lambda表达式,不是方法,而是一个函数类型的对象。
什么是高阶函数
就是把函数作为参数直接传递给方法,但是这个函数不能是个普通的函数,需要是 匿名函数, 或者是lambda表达式, 或者函数类型的引用 (:: + 函数名)
private fun loginE(user: String, pwd: String, repository: (Boolean) -> Unit) {
if (user == "admin" && pwd == "11111") {
repository.invoke(true)
} else {
repository.invoke(false)
}
}
private fun test() {
loginE("admin", "111111", fun(b: Boolean): Unit { Log.i("", b.toString()) })
loginE("admin", "111111", fun(b: Boolean) { Log.i("", b.toString()) })
loginE("admin", "111111", { b -> Log.i("", b.toString()) })
loginE("admin", "111111") { b -> Log.i("", b.toString()) }
loginE("admin", "111111") { Log.i("", it.toString()) }
loginE("admin", "111111", ::niming)
}
private fun niming(b: Boolean) {
Log.i("", b.toString())
}
如果是一个完整的方法 则会报错 (禁止使用名称的匿名函数)
最后的彩蛋1. Lambda的不同写法
```kotlin
fun lambda() {
//Todo () -> Unit
val m01 = { println("Hello") }
m01.invoke()
//Todo () -> String
val m02 = { "Hello" }
//Todo (Int) -> String
val m03 = { num1: Int -> num1.toString() }
//Todo (Int) -> String
val m04 = { num1: Int, num2: Int -> num1 + num2 }
//Todo (Int) -> String
var m05: (Int) -> String // 函数声明
m05 = fun(num: Int): String = num.toString() // 函数的实现
//Todo (Int, Int) -> String
val m06: (Int, Int) -> String = fun(num1, num2) = num1.toString() + num2.toString()
//Todo (String, String) -> Unit 其实这里是形参
val m07: (String, String) -> Unit = { a, b -> println("Hello") }
//Todo (String) -> Int
val m08: (String) -> Int = {
println("Hello: $it")
8023
}
//Todo (Int) -> Unit
val m09: (Int) -> Unit = {
when (it) {
1 -> println("数字:1")
in 20..60 -> println("数字:20-26 之内的数字")
else -> println("其他")
}
}
//Todo (Int,Int) -> Unit 下划线是拒绝收该值
val m10: (Int, Int) -> Unit = { _, num ->
when (num) {
1 -> println("数字:1")
in 20..60 -> println("数字:20-26 之内的数字")
else -> println("其他")
}
}
//Todo (Any) -> Any
var m11: (Any) -> Any = { str -> str }
//Todo (Any) -> Any (Any) -> Unit
var m11_1: (Any) -> Any = { _ -> }
println("Any:" + m11_1.invoke("")) //Any:kotlin.Unit
//Todo (Char) -> Unit
var m12 = { sex: Char -> if (sex == '男') println("先生") else println("女士") }
//Todo 扩展函数
var m13: String.() -> Unit = {
}
}
最后的彩蛋2.kotlin手写RxJava 核心代码
fun main(args: Array<String>) {
create {
""
}.map {
111
}.map {
""
}.observer<Int> {
}
}
class Help
er<T>(var item: T) {
fun <R> map(action: T.() -> R) = Helper(action(item))
fun <R> observer(action: T.() -> Unit) = Helper(action(item))
}
fun <R> create(action: () -> R) = Helper(action())