将数组传递给Swift中具有可变数量的args的函数

Ole*_*ann 141 variadic-functions swift

Swift编程语言中,它说:

函数也可以采用可变数量的参数,将它们收集到一个数组中.

  func sumOf(numbers: Int...) -> Int {
      ...
  }
Run Code Online (Sandbox Code Playgroud)

当我用逗号分隔的数字列表(`sumOf(1,2,3,4))调用这样的函数时,它们可以作为函数内的数组使用.

问:如果我已经有一个数字数组要传递给这个函数怎么办?

let numbers = [1, 2, 3, 4]
sumOf(numbers)
Run Code Online (Sandbox Code Playgroud)

这会因编译器错误而失败,"无法找到接受所提供参数的'__conversion'的重载".有没有办法将现有数组转换为可以传递给可变函数的元素列表?

man*_*lds 89

正如开发人员所证实的,Splatting还没有语言.现在的解决方法是使用重载或等待,如果您不能添加重载.

  • Splatting 还在语言中吗?我正在尝试调用 `sumOf(...numbers)` (4认同)
  • 太令人失望了!即使是像尝试将我自己的日志调用委托给“print”这样简单的事情,我也遇到了这个问题! (2认同)

Log*_*gan 59

这是我发现的一项工作.我知道这不是你想要的,但似乎有效.

第1步:使用数组而不是可变参数声明您想要的函数:

func sumOf(numbers: [Int]) -> Int {
    var total = 0
    for i in numbers {
        total += i
    }
    return total
}
Run Code Online (Sandbox Code Playgroud)

第2步:从可变参数函数中调用它:

func sumOf(numbers: Int...) -> Int {
    return sumOf(numbers)
}
Run Code Online (Sandbox Code Playgroud)

第3步:呼叫任何一种方式:

var variadicSum = sumOf(1, 2, 3, 4, 5)
var arraySum = sumOf([1, 2, 3, 4, 5])
Run Code Online (Sandbox Code Playgroud)

这看起来很奇怪,但它在我的测试中起作用.如果这会导致任何人无法预料的问题,请告诉我.Swift似乎能够用相同的函数名来区分两个调用之间的差异.

此外,使用此方法,如果Apple更新语言@ manojid的答案建议,您只需要更新这些功能.否则,您将不得不经历并进行大量重命名.


Guo*_*ang 13

你可以施放这个功能:

typealias Function = [Int] -> Int
let sumOfArray = unsafeBitCast(sumOf, Function.self)
sumOfArray([1, 2, 3])
Run Code Online (Sandbox Code Playgroud)

  • 这是一个非常糟糕的主意。这绝对是零保证。 (2认同)
  • @MattMc 当然。据我所知,没有什么可以让您简单地使用“unsafeBitCast”将一种可调用类型转换为另一种可调用类型。这在今天可能有效,但除非参考文献这么说,否则编译器的下一个版本可以自由地在这里执行任何操作(编译器错误/崩溃/随机执行代码...)。看看 [unsafeBitCast](https://developer.apple.com/documentation/swift/1641250-unsafebitcast) 上的严肃警告。 (2认同)

GoZ*_*ner 12

您可以使用辅助函数:

func sumOf (numbers : [Int])  -> Int { return numbers.reduce(0, combine: +) }
func sumOf (numbers : Int...) -> Int { return sumOf (numbers) }
Run Code Online (Sandbox Code Playgroud)

  • 只要有一个数组版本.我认为这个问题的前提是原始函数需要`Int ...`而且不能(容易)改变? (10认同)
  • @delnan:正确.在我看来,应该有办法将数组传递给可变参数函数,因为无论如何变量参数都变成了一个数组. (2认同)