我正在努力解决这个问题:
创建一个接受整数数组的函数,该函数通过引用传递,将对数组执行操作并返回Int结果。
我有问题。经过多次搜索,我将问题分解为多段代码,以孤立地测试每一段代码。
我简单的"通过参考代码传递函数"是:
func counter(start:Int)->String{
for var i = 0 ; i<start; ++i{
println("I => (i)")
}
return "Done"
}
func test(i:Int, inout f:(Int)->String){
f(i)
}
test(5,&counter)
问题是,即使是我通过引用传递函数的简单测试也会失败:
(Int)->String is not convertible to @lvalue inout $T3
如果我这样做:
func counter(end:Int)->String{
for var i = 0 ; i<end; ++i{
println("I => (i)")
}
return "Done"
}
func test(i:Int, inout f:(Int)->String){
f(i)
}
var f1 = counter
test(5,&f1)//pass a reference as an argument to the function
这是参考通行证吗?由于这是有效的,我不确定这是正确的。
我做错了什么?
首先,通过引用传递(inout
)适用于以下情况:例如,您需要将参数分配给被调用函数内部的参数,并将其分配给调用范围中的传递变量,或者您需要对其调用mutating
方法并将其反映在调用范围中,等等。
您没有在test
中分配给f
。因此,使其成为inout
是没有意义的,因为它限制了可以传递给它的内容
要从技术上回答为什么会出现错误,答案是不能通过引用传递常量变量(即let
),而counter
是常量变量(不能分配给counter
)。您可以将用于在顶层定义函数的func
语法想象为类似于具有闭包表达式的let
:
func counter(start:Int)->String{ ... }
就像
let counter : Int->String = { (start:Int)->String in ... }
如果参数和返回类型匹配,只需按原样传递函数即可。
你根本不需要&...
。
编译器告诉您inout f:(Int)->String
与counter()
函数的函数类型不同。如果从test
函数中删除inout
关键字,并在函数调用中删除&
,则一切正常。
你确定这个练习不是要求你通过引用传递数组吗?