用代码实例解释Kotlin lambda

192 阅读4分钟

在编程中,lambda表达式是一个匿名函数,它被写成一个表达式。

由于lambda是一个表达式,它可以作为一个参数传递给一个函数或作为一个函数执行的返回值。

许多编程语言都有自己的lambda表达式语法。在Kotlin中,lambda表达式的语法如下:

var [name] : [input type(s)] -> [output type] = { [arguments] -> [body] }

上面的语法可能会让你感到困惑,所以让我们看看Kotlin lambda表达式的一个有效例子。

考虑下面这个makeUppercase() 函数:

var makeUppercase : (String) -> String = { str -> str.uppercase() }

现在让我解释一下上面的例子。

上面的lambda表达式的名字是makeUppercase

: (String) -> String 语法意味着该函数接受一个类型为String 的输入,并同时返回一个类型为String 的值。

{ str -> str.uppercase() } 语法是lambda表达式的主体。在这种情况下,输入参数被命名为str 。你不需要明确地声明str 的类型,因为它已经在[input type] 语法中声明了。

表达式的主体只是调用String 实例的.uppercase() 方法。

现在你已经定义了一个lambda表达式,你可以像其他函数一样调用makeUppercase()

makeUppercase("nathan") // NATHAN
makeUppercase("sarah") // SARAH

lambda表达式需要明确地定义一个返回类型。当你想不返回任何东西时,你可以将返回类型定义为Unit

var makeUppercase: (String) -> Unit = { str ->
println(str.uppercase())
}

当你需要为你的lambda表达式定义多个参数时,你可以添加用逗号分隔的参数类型。

下面的例子创建了一个接受3个参数的lambda表达式:一个String ,一个Int ,和一个Boolean

var myLambda: (String, Int, Boolean) -> Unit = { str, num, bool ->
println("$str $num $bool")
}
myLambda("nathan", 1, true) // nathan 1 true

另外,你可以将λ表达式的输入和输出类型定义从= 符号的左边移到右边,如下所示:

val makeUppercase = { str: String -> str.uppercase() }

在上面的例子中,参数类型被定义为String ,而返回类型是由lambda主体推断出来的。

it 关键字

当你的lambda表达式只包含一个参数时,你可以使用it 关键字来指代那个参数,而不是你定义的自定义名称。

考虑一下下面的例子:

val plusTwo : (Int) -> Int = { it + 2 }
plusTwo(4) // 6

在上面的plusTwo() 函数中,单个输入参数被称为it ,所以你不需要在大括号内定义参数列表{}

it 关键字将永远指代你传入函数的单一参数,所以当它是一个String ,你可以在关键字上调用String 方法:

val makeUppercase : (String) -> String = { it.uppercase() }

请记住,当你的lambda表达式有一个以上的参数时,it 关键字将抛出一个unresolved reference 错误。

把lambda表达式写在圆括号外。

当你把lambda表达式作为函数调用的最后一个参数传递时,你可以把表达式写在包含参数的括号外。

例如,当使用Array 类构造函数创建一个数组时:

val myArray = Array(3) { i -> i * 2 }
// equals to

val myArray = Array(3, { i -> i * 2 })

带有函数指针的Kotlin lambda

最后,当你的lambda表达式主体只有一个函数调用时,你可以使用函数指针语法(::)来调用该函数,而不是正常的.functionName()

看一下下面的例子:

val makeUppercase: (String) -> String = String::uppercase

使用函数指针,你可以去掉大括号{} ,lambda主体就变成了一个单一的::uppercase 调用。

Kotlin lambda的常见例子

Kotlin lambda表达式通常在你调用一个需要一个函数作为参数的函数时使用。

例如,用于迭代一个值的forEach 方法接受一个lambda表达式,如下所示:

val name = "Nathan"
name.forEach { c -> print(c) } // Nathan

当你调用Array 方法时,也需要一个lambda表达式,比如mapreduce:

val numbers = arrayOf(1, 2, 3)
val newNumbers = numbers.map { n -> n + 2 }
newNumbers.toString() // [3, 4, 5]

val aSum = numbers.reduce { accumulator, currentEl ->
accumulator + currentEl
}
aSum.toString() // 1 + 2 + 3 = 6

当你创建一个Android应用程序时,你可能也会使用lambda表达式作为监听器的主体。

例如,这里是一个AndroidButton ,它的setOnClickListener lambda表达式。

val button = findViewById<Button>(R.id.my_button)
button.setOnClickListener {
Toast.makeText(this, "Hello", Toast.LENGTH_SHORT).show()
}

现在你已经学会了λ表达式在Kotlin中的工作方式。干得好!👍