kotlin方法传入lambda表达式参数并调用invoke什么意思
Posted Jason_Lee155
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了kotlin方法传入lambda表达式参数并调用invoke什么意思相关的知识,希望对你有一定的参考价值。
1. Lambda表达式 简介
作用 : Lambda 表达式可以作为函数参数 , 传递到函数中 , 使代码结构更加紧凑 ;
应用场景 : 集合中扩展集合操作 , 当做函数参数 , 替代匿名内部类 ;
好处 : Lambda 表达式语法简洁 , 避免了冗长的函数声明调用过程 ;
函数式编程 : 函数作为输入和输出 ; 在集合操作中 , 过滤 filter , 映射 map 等操作传入 Lambda 表达式 作为参数 , 很好地体现了函数式编程思想 ;
2. Lambda表达式 语法
a : Int, b : Int -> a + b
示例说明 : 上面的代码示例是 Lambda 表达式的标准形式 , 其参数列表是 a : Int, b : Int , 在 -> 后面的函数体中, 可以直接调用 a 和 b 两个变量 ;
大括号 : Lambda 表达式需要完整的写在大括号中 , 其参数列表 , 执行代码 , 返回值 , 都写在一个大括号 里 ;
参数列表 : Lambda 表达式的参数列表 , 定义在 “->” 符号之前 , 格式为 “变量名 : 变量类型” , 多个参数使用逗号隔开 ;
函数体 : Lambda 表达式的函数体可以由 1 11 行 , 也可以有多行 , 最后一行默认是 Lambda 表达式的返回值 ;
-> 符号 : 用于分割 参数列表 与 函数体 ;
3. Lambda 表达式类型
分析下面示例中的 var add : (Int, Int)->Int 变量类型声明部分 ;
var add : (Int, Int)->Int = a : Int, b : Int ->
println("计算 : a + b = $a + b")
a + b
变量或常量 : Lambda 表达式可以声明成变量 var , 也可以声明成常量 val ;
变量 / 常量 名称 : 符合标识符规则即可 ;
Lambda 表达式参数列表 : 在括号中 () 表示 , 如果没有参数 , 括号内空着即可 , 如果有多个参数使用逗号隔开 ;
-> 符号 : 在 Lambda 表达式类型中 , 用于分割 参数列表 和 返回值类型 ;
Lambda表达式返回值 : 只允许有一个返回值 , 在 -> 符号之后 , 如果返回值为空 , 记作 Unit ;
看几个示例 :
无参数 空类型返回值 的 Lambda 表达式 类型 : ()->Unit , 无参数 () 内空着 , 返回值为空 , 记作 Unit ;
// 无参数 Unit 空类型返回值的 Lambda 表达式
var lambda1 : ()-> Unit = println("lambda1")
单个参数 Int 类型返回值 的 Lambda 表达式 类型 : (Int)->Int , 其参数是 Int 类型 , 返回值也是 Int 类型的 ;
// Int 类型参数 , Int 类型返回值 , 的 Lambda 表达式
var lambda2 : (Int)-> Int = a : Int -> a + 1000
多个参数 Int 类型返回值 的 Lambda 表达式 类型 : (Int, Int)->Int , 其有两个 Int 类型参数 , 使用逗号隔开 ;
// 多个参数的 Lambda 表达式
var lambda4 : (Int, Int)->Int = a : Int, b : Int ->
println("计算 : a + b = $a + b")
a + b
使用 Lambda 表达式作为参数,Int 返回值类型 的 Lambda 表达式类型 : (Int, Int, (Int, Int)->Int)->Int , 该 Lambda 表达式类型有 3 个参数 , 分别是两个 Int 和 (Int, Int)->Int , 最后一个参数的类型是 Lambda 表达式类型 ;
// Lambda 表达式类型作为参数的 Lambda 表达式 , 第 3 个参数是 Lambda 表达式类型的参数
var lambda5 : (Int, Int, (Int, Int)->Int)->Int = a : Int, b : Int, c : (Int, Int)->Int ->
println("计算 : a + b = $c.invoke(a, b)")
c.invoke(a, b)
这里关于 Unit 空类型说明一下 , 如果没有参数 , 括号中空着即可 , 如果返回值为空类型 , 必须写成 Unit 类型的返回值 , 相当于 Java 中的 void 空类型 ;
4. Lambda 表达式返回值
// 多个参数的 Lambda 表达式
var lambda4 : (Int, Int)->Int = a : Int, b : Int ->
println("计算 : a + b = $a + b")
a + b
返回值设置 : Lambda 表达式的返回值是 Lambda 表达式函数体的最后一行 ;
代码解析 : 如上述代码 , 其函数体部分有两行组成 , 第一行 println("计算 : a + b = $a + b") 打印计算公式 , 第二行才是真正的返回值 , 表示返回 a + b 的值 , 作为 Lambda 表达式的返回值 ;
调用返回值 : 即使用 lambda4.invoke( 1 , 2 ) 或 lambda4 ( 1, 2 ) 调用 Lambda 表达式 , 返回 1 + 2 = 3 计算结果 , 最终都返回 3 ;
返回值类型错误 : 注意不要放错位置 , 如果最后一行的结果类型 , 与 Lambda 表达式的类型不一致 , 不是 Int 类型的返回值 , 会导致错误产生 ; 如下图示例 , 在最后一行写成字符串类型 , 编译时直接报错 ;
5. Lambda 表达式调用
Lambda 表达式调用 : 使用 invoke 方法 , 或直接当做函数调用 , 即可调用 Lambda 表达式 ;
直接调用 : 调用格式为 “Lambda表达式变量 / 常量 ( 实际参数列表 )” ;
invoke 调用 : 调用格式为 “Lambda表达式变量 / 常量.invoke( 实际参数列表 )” ;
Lambda 表达式 代码示例 :
// 4 . 多个参数的 Lambda 表达式
var lambda4 : (Int, Int)->Int = a : Int, b : Int ->
println("计算 : a + b = $a + b")
a + b
使用 lambda4.invoke(1, 2) 和 lambda4(1, 2) 两种形式 , 都可以调用 Lambda 表达式
fun main()
println("$lambda4.invoke(1, 2)")
println("$lambda4(1, 2)")
两种调用方式实现的效果是一样的 :
计算 : a + b = 3
3
计算 : a + b = 3
3
6. Lambda 表达式完整语法示例 ( 声明 | 实现 | 调用 )
下面的示例中 , 分别声明了 5 55 种不同类型的 Lambda 表达式示例 , 并使用不同的方法进行调用:
// 1 . 无参数 Unit 空类型返回值的 Lambda 表达式
var lambda1 : ()-> Unit = println("lambda1")
// 2 . Int 类型参数 , Int 类型返回值 , 的 Lambda 表达式
var lambda2 : (Int)-> Int = a : Int -> a + 1000
// 3 . 多行代码的 Lambda 表达式, 最后一行是返回值
var lambda3 : (Int)-> Int = a : Int ->
println("lambda3 多行代码")
a + 1000
// 4 . 多个参数的 Lambda 表达式
var lambda4 : (Int, Int)->Int = a : Int, b : Int ->
println("计算 : a + b = $a + b")
a + b
// 5 . Lambda 表达式类型作为参数的 Lambda 表达式 , 第 3 个参数是 Lambda 表达式类型的参数
var lambda5 : (Int, Int, (Int, Int)->Int)->Int = a : Int, b : Int, c : (Int, Int)->Int ->
println("计算 : a + b = $c.invoke(a, b)")
c.invoke(a, b)
fun main()
//1 . 调用 无参数 Unit 空类型返回值的 Lambda 表达式 , 分别用两种形式进行调用
println("\\n执行 lambda1 调用 : \\n")
println("$lambda1.invoke()")
println("$lambda1()")
//2 . Int 类型参数 , Int 类型返回值 , 的 Lambda 表达式
println("\\n执行 lambda2 调用 : \\n")
println("$lambda2.invoke(100)")
println("$lambda2(100)")
//3 . 调用 多行代码的 Lambda 表达式
println("\\n执行 lambda3 调用 : \\n")
println("$lambda3.invoke(200)")
println("$lambda3(200)")
//4 . 调用 多个参数的 Lambda 表达式
println("\\n执行 lambda4 调用 : \\n")
println("$lambda4.invoke(1, 2)")
println("$lambda4(1, 2)")
//5 . 调用 Lambda 表达式类型作为参数的 Lambda 表达式 , 第 3 个参数是 Lambda 表达式类型的参数
println("\\n执行 lambda5 调用 : \\n")
println("$lambda5.invoke(3 , 4 , lambda4)")
println("$lambda5(3 , 4 , lambda4)")
执行结果 :
执行 lambda1 调用 :
lambda1
kotlin.Unit
lambda1
kotlin.Unit
执行 lambda2 调用 :
1100
1100
执行 lambda3 调用 :
lambda3 多行代码
1200
lambda3 多行代码
1200
执行 lambda4 调用 :
计算 : a + b = 3
3
计算 : a + b = 3
3
执行 lambda5 调用 :
计算 : a + b = 7
计算 : a + b = 7
计算 : a + b = 7
7
计算 : a + b = 7
计算 : a + b = 7
计算 : a + b = 7
7
逻辑有点乱,但是主要意思还是表达清楚了的。
以上是关于kotlin方法传入lambda表达式参数并调用invoke什么意思的主要内容,如果未能解决你的问题,请参考以下文章
Kotlin标准库函数 ① ( apply 标准库函数 | let 标准库函数 )
Tkinter Button按钮组件如何调用一个可以传入参数的函数
Kotlin函数 ⑥ ( 函数参数为 Lambda 表达式 | Lambda 表达式作为参数的简略写法 | 唯一参数的简略写法 | 最后一个参数的简略写法 )