如何通过引用传递函数



我正在努力解决这个问题:

创建一个接受整数数组的函数,该函数通过引用传递,将对数组执行操作并返回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)->Stringcounter()函数的函数类型不同。如果从test函数中删除inout关键字,并在函数调用中删除&,则一切正常。

你确定这个练习不是要求你通过引用传递数组吗?

最新更新