Function 第二次调用iterate时到底发生了什么?
我在Kotlin中有以下代码:Function 第二次调用iterate时到底发生了什么?,function,kotlin,Function,Kotlin,我在Kotlin中有以下代码: fun iterate(第一个:String,第二个:String,iter:Int,func:(String,String)->String){ 对于(i在0..iter中) println(func(第一、第二)) } 有趣的连接(一:字符串,二:字符串):字符串{ 返回“$1$2”; } 趣味主线(args:Array){ 迭代(“我”,“你”,5,::串联) 迭代(“另一个”,“一个”,6){a,b->a+b} } 有人能解释一下在第二次调用iterat
fun iterate(第一个:String,第二个:String,iter:Int,func:(String,String)->String){
对于(i在0..iter中)
println(func(第一、第二))
}
有趣的连接(一:字符串,二:字符串):字符串{
返回“$1$2”;
}
趣味主线(args:Array){
迭代(“我”,“你”,5,::串联)
迭代(“另一个”,“一个”,6){a,b->a+b}
}
有人能解释一下在第二次调用iterate函数时花括号中发生了什么吗?我是否要超越它?
此外,我还尝试在函数声明中交换
func
和iter
paratemers。这样,我就不能再在第二次调用中使用花括号并插入代码,因为我不知道把iter参数放在哪里。您的func
参数的类型是一个函数-它的类型是(String,String)->String
,这意味着它需要两个String
参数(在括号中)并返回一个字符串(箭头后)
这就是所有函数类型的外观,(x)->y
。不带参数且不返回值的函数类型有一个类型()->Unit
(因为每个函数都返回Kotlin中的某些内容,Unit
是“无意义值”类型)
因此,对于func
参数,您可以传入该类型的任何函数-接受两个字符串,返回一个字符串。您的串联
函数与之匹配,因此您可以将其传入-您使用的是函数引用,::串联
是传递该函数的一种方式-它是对该函数的引用
通过第二次iterate
调用,您将创建一个要传入的函数对象,而不是引用在类上声明为实际方法的函数对象。您使用的lambda接受两个参数,a
和b
,并对它们调用+
(并隐式返回该值作为结果)
现在您并不是说它们是String
s(如果需要,您可以显式声明它们的类型),但是类型系统基本上是检查这是否可以应用于两个String
变量,并且+
对这些变量的结果也将是String
。因此,它可以正常工作,并且可以在iterate
函数中使用
就像@IR42在注释中所说的那样,您使用的是-基本上当函数调用中的最后一个参数是lambda时,您可以将它移到外部(如果lambda是其中唯一的参数,则可以删除括号)
但这只有在它是最后一个参数时才起作用——否则它就无法确定您搬出了哪一个这就是为什么不能更改顺序并保留尾随lambda。您可以切换订单,但通话必须如下所示:
iterate("Me", "You", ::concatenation, 5)
iterate("Another", "One", {a, b -> a + b}, 6)
func
参数的类型是一个函数-它的类型是(String,String)->String
,这意味着它接受两个String
参数(在括号中),并返回一个字符串(在箭头后面)
这就是所有函数类型的外观,(x)->y
。不带参数且不返回值的函数类型有一个类型()->Unit
(因为每个函数都返回Kotlin中的某些内容,Unit
是“无意义值”类型)
因此,对于func
参数,您可以传入该类型的任何函数-接受两个字符串,返回一个字符串。您的串联
函数与之匹配,因此您可以将其传入-您使用的是函数引用,::串联
是传递该函数的一种方式-它是对该函数的引用
通过第二次iterate
调用,您将创建一个要传入的函数对象,而不是引用在类上声明为实际方法的函数对象。您使用的lambda接受两个参数,a
和b
,并对它们调用+
(并隐式返回该值作为结果)
现在您并不是说它们是String
s(如果需要,您可以显式声明它们的类型),但是类型系统基本上是检查这是否可以应用于两个String
变量,并且+
对这些变量的结果也将是String
。因此,它可以正常工作,并且可以在iterate
函数中使用
就像@IR42在注释中所说的那样,您使用的是-基本上当函数调用中的最后一个参数是lambda时,您可以将它移到外部(如果lambda是其中唯一的参数,则可以删除括号)
但这只有在它是最后一个参数时才起作用——否则它就无法确定您搬出了哪一个这就是为什么不能更改顺序并保留尾随lambda。您可以切换订单,但通话必须如下所示:
iterate("Me", "You", ::concatenation, 5)
iterate("Another", "One", {a, b -> a + b}, 6)
函数iterate()
包含四个参数:两个字符串、Int和一个函数
调用iterate()
时,可以通过几种方式给出字符串参数:例如,可以给出包含字符串的变量的名称(例如one
);或者您可以给出一个文本字符串值(例如“Me”
)
你也可以用这两种方式给出函数参数*
第一种方法的等价物是为现有函数指定一个值。 这就是::串联的含义。 (:
用于创建函数引用。)
第二种方法的等价物是使用a,这是一种写出函数内容的方法。 {a,b->a+b}
是一个lambda:它是一个接受两个参数并返回它们的串联的函数。 (在这种情况下,编译器可以从上下文中判断
iterate("Another", "One", 6, {a, b -> a + b})
with (someObject) {
// In here, ‘this’ refers to someObject.
}
iterate("Another", "One", {a, b -> a + b}, 6)