kotlin匿名函数
匿名函数
定义
定义时不取名字的函数,我们称之为匿名函数.
我们将把匿名函数改称为 lambda,将它的定义改称为 lambda表达式,它的返回数据改称为 lambda 结果。
匿名函数通常整体传递给其他函数,或者从其他函数返回。
- 定义一个匿名函数
fun main(args: Array<String>) {
println({
val currentYear = 2018
"Welcome to SimVillage, Mayor! (copyright $currentYear)"
}())
}
定义字符串就是把字符放在一对引号中间。类似地,定义函数就是把表达式或语句放在一对花括号里。这里,你首先调用 println 函数。在一对花括号里定义一个匿名函数,将其放在println 函数的参数圆括号里。匿名函数里定义了一个变量,返回一条欢迎字符串信息。
{
val currentYear = 2018
"Welcome to SimVillage, Mayor! (copyright $currentYear)"
}
我们在花括号的后面跟上一对空的圆括号,表示调用匿名函数。圆括号不能省,否则就不会输出欢迎信息。和具名函数一样,要让匿名函数工作,就得调用它,并在参数圆括号里传入对应的值参(没参数就空着):
{
val currentYear = 2018
"Welcome to SimVillage, Mayor! (copyright $currentYear)"
}()
函数类型
定义一个存储函数的变量,把输出欢迎语句的匿名函数赋给它。
- 把匿名函数赋值给变量
fun main(args:Array<String>) {
val helloFunction : () -> String = {
"hello world"
}
println(helloFunction())
}
定义变量时,是在变量名后面跟上冒号和类型。greetingFunction: () -> String 代码片段也是这样做的。
对编译器来讲,: Int 表示变量存储的是哪种类型的数据(整数),: () -> String 表示变量存储的是哪种类型的函数。
函数类型定义包括两个部分,它们以箭头符号隔开:一对圆括号里面的函数参数和紧跟着的返回数据类型。
fun helloFunction() : String
| |
() -> String
() -> String 是你给 helloFunction 变量指定的函数类型定义,它告诉编译器,任何不需要参数(以圆空括号表示)、能返回 String 的函数,都可以赋给greetingFunction 变量。
和变量的类型定义一样,无论匿名函数是赋给 helloFunction 变量,还是作为值参传递,
编译器都会进行检查以确保它的类型满足要求。
隐式返回
val greetingFunction: () -> String = {
val currentYear = 2018
"Welcome to SimVillage, Mayor! (copyright $currentYear)"
}
匿名函数不需要 return 关键字来返回数据。没有 return 关键字,为了返回数据,匿名函数会隐式或自动返回函数体最后一行语句的结果。
这个特性不仅很方便,也是匿名函数语法的特别要求。之所以不能用 return 关键字,是因为编译器不知道返回数据究竟是来自调用匿名函数的函数,还是匿名函数本身。
带有函数参数
匿名函数需要带参数时,参数的类型放在匿名函数的类型定义中,参数名则放在函数定义中。
fun main(args:Array<String>) {
val helloFunction : (String) -> String = { name ->
"hello world" + name
}
println(helloFunction("naruto"))
}
现在匿名函数有了一个 String 类型的参数。具体的写法如下:在匿名函数体内,左花括号的后面,写上 String 类型的参数名,后面再跟上一个箭头符号。
val greetingFunction: (String) -> String = { playerName ->
it 关键字
定义只有一个参数的匿名函数时,可以使用 it 关键字来表示参数名。当你有一个只有一个参数的匿名函数时,it 和命名参数都有效.
fun main(args:Array<String>) {
val itFunction : (String) -> (String) = {
"$it"+"hhhh"
}
println(itFunction("hello"))
}
多个参数
如果有多个参数,需要使用命名参数。
fun main(args:Array<String>) {
val itFunction : (String,String) -> (String) = {param1,param2->
param1 + "---->" + param2
}
println(itFunction("hello","world"))
}
类型推断
Kotlin 的类型推断规则同样也适用函数类型:定义一个变量时,如果已把匿名函数作为变量值赋给它,就不需要显式指明变量类型了.
- 不带参数的匿名函数
val greetingFunction: () -> String = {
val currentYear = 2018
"Welcome to SimVillage, Mayor! (copyright $currentYear)"
}
类型推断
val greetingFunction = {
val currentYear = 2018
"Welcome to SimVillage, Mayor! (copyright $currentYear)"
}
- 带参数的匿名函数,但为了帮助编译器更准确地推断变量类型,匿名函数的参数名和参数类型必须有
fun main(args:Array<String>) {
val itFunction : (String,String) -> (String) = {param1,param2->
param1 + "---->" + param2
}
println(itFunction("hello","world"))
}
类型推断
fun main(args:Array<String>) {
val itFunction = {param1 : String,param2:String ->
param1 + "---->" + param2
}
println(itFunction("hello","world"))
}
定义参数是函数的函数
一个函数类型的参数定义起来和其他类型的参数一样:在函数名后的一对圆括号内列出,再加上类型。
fun main(args: Array<String>) {
val greetingFunction = { playerName: String, numBuildings: Int ->
val currentYear = 2018
println("Adding $numBuildings houses")
"Welcome to SimVillage, $playerName! (copyright $currentYear)"
}
runSimulation("Guyal", greetingFunction)
}
fun runSimulation(playerName: String, greetingFunction: (String, Int) -> String) {
val numBuildings = (1..3).shuffled().last() // Randomly selects 1, 2, or 3
println(greetingFunction(playerName, numBuildings))
}
runSimulation 函数有两个参数,一个是玩家的名字,一个是 greetingFunction。其中,greetingFunction 也是一个函数,它也有两个参数,一个 String 类型和一个 Int 类型,它返回 String 类型的数据。
简略语法
在 Kotlin 中,可以使用简略语法传入 Lambda 表达式作为函数的参数。如果函数的最后一个参数是一个 Lambda 表达式,那么可以将该表达式写在调用括号外面,并使用大括号 {}
包裹起来,从而省略掉部分冗余的语法。这种简略语法可以使代码更加简洁易读。
// 定义函数类型的参数
fun performRequest(url: String, callback: (String) -> Unit) {
// 执行请求操作...
val response = "Response from $url"
// 调用回调函数
callback(response)
}
// 使用简略语法传入 Lambda 表达式作为参数
performRequest("https://my.api.com") { response ->
println(response)
}
在这个例子中,我们定义了一个名为 performRequest
的函数,它接受一个字符串类型的 URL 和一个函数类型的参数 callback
,该参数表示请求完成后的回调函数。在函数体内,我们模拟了一个请求操作,并生成了一个响应字符串。接着,我们调用了回调函数,并传递了该响应字符串作为参数。
在函数调用时,我们使用了简略语法,将 Lambda 表达式写在了调用括号外面,并使用大括号 {}
包裹起来。Lambda 表达式接受一个字符串参数 response
,并在函数体内打印了该参数的值。
需要注意的是,使用简略语法时,只有当 Lambda 表达式是函数的最后一个参数时才能省略掉部分冗余的语法,否则需要显式地指定参数名称和类型。
函数类型作为返回类型
和其他数据类型一样,函数类型也是有效的返回类型,也就是说,你可以定义一个能返回函数的函数。
fun main(args: Array<String>) {
runSimulation()
}
fun runSimulation() {
val greetingFunction = configureGreetingFunction()
println(greetingFunction("Guyal"))
}
fun configureGreetingFunction(): (String) -> String {
val structureType = "hospitals"
var numBuildings = 5
return { playerName: String ->
val currentYear = 2018
numBuildings += 1
println("Adding $numBuildings $structureType")
"Welcome to SimVillage, $playerName! (copyright $currentYear)"
}
}