function - 在第二次迭代调用中到底发生了什么?
问题描述
我在 Kotlin 中有以下代码:
fun iterate(first: String, second: String, iter: Int, func: (String, String) -> String) {
for(i in 0..iter)
println(func(first, second))
}
fun concatenation(one: String, two: String): String {
return "$one $two";
}
fun main(args: Array<String>) {
iterate("Me", "You", 5, ::concatenation)
iterate("Another", "One", 6) {a, b -> a + b}
}
谁能解释第二次调用 iterate 函数时大括号中发生了什么?我要覆盖它吗?另外,我尝试在函数声明中交换func
和参数。iter
这样我就不能再在第二次调用中使用大括号并插入代码,因为我不知道在哪里放置 iter 参数。
解决方案
您的func
参数的类型是一个函数 - 它的类型是(String, String) -> String
这意味着它需要两个String
参数(在括号中)并返回一个String
(在箭头之后)。
这就是所有函数类型的样子,(x) -> y
. 不带参数且不返回值的函数类型具有类型(因为在 Kotlin 中() -> Unit
每个函数都返回某些Unit
内容,因此是“无意义值”类型)。
因此,对于您的func
参数,您可以传入任何具有该类型的函数 - 接受两个字符串,返回一个字符串。您的concatenation
函数与之匹配,因此您可以将其传入 - 您正在使用函数引用,::concatenation
这是传递该函数的一种方式 - 它是对它的引用。
在您的第二次iterate
调用中,您正在创建一个要传入的函数对象,而不是引用一个在类上声明为实际方法的函数对象。您正在使用一个接受两个参数的 lambdaa
和b
, 并调用+
它们(并隐式返回该值作为结果)。
现在你不是说它们在String
这里(如果你愿意,你可以显式声明它们的类型),但类型系统基本上是检查这是否可以应用于两个String
变量,并且+
on 的结果也将是String
. 所以一切正常,它可以在你的iterate
函数中使用。
就像@IR42 在评论中所说,您使用的是尾随 lambda - 基本上当函数调用中的最后一个参数是 lambda 时,您可以将其移到外面(如果 lambda是那里唯一的东西)。
但这仅在它是最后一个参数时才有效 - 否则它不会确定您移出哪个参数!- 这就是为什么您不能更改顺序并保留尾随 lambda 的原因。您可以切换顺序,但调用必须是这样的:
iterate("Me", "You", ::concatenation, 5)
iterate("Another", "One", {a, b -> a + b}, 6)
推荐阅读
- android - TextView wrap_content 在回收站视图项中不起作用
- sql - 自动创建 Sybase 用户
- excel - 使用 VBA 对随机表进行排序
- javascript - Google 表格和外部 API
- hyperledger-fabric - 在多通道多链码和多账本 Fabric 网络上访问账本
- java - 如何在构建时从 .class 文件中的 gradle.properties 获取值
- c - 带有 WSL 的 NCurses 不正确地显示框
- .net - Microsoft.Scripting.ArgumentTypeException:预期填充,得到填充
- python - centos安装python3.7时出现的问题
- python - Pyserial 正在从 arduino 获取不一致的数据