将数组传递给 Swift 中参数数目可变的函数

快速编程语言表示:

函数还可以接受数量可变的参数,并将它们收集到一个数组中。

  func sumOf(numbers: Int...) -> Int {
...
}

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

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

let numbers = [1, 2, 3, 4]
sumOf(numbers)

此操作失败,出现编译器错误,“无法找到接受所提供参数的‘ _ _ version’的重载”。有没有一种方法可以将现有的数组转换成元素列表,然后传递给可变参数函数?

95840 次浏览

您可以这样使用助手函数:

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

这是我找到的一份工作。我知道这不是你想要的,但似乎起作用了。

步骤1: 用数组而不是变量参数声明你想要的函数:

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

第二步: 在你的可变参数函数内称之为:

func sumOf(numbers: Int...) -> Int {
return sumOf(numbers)
}

第三步: 打电话给任何一种方式:

var variadicSum = sumOf(1, 2, 3, 4, 5)
var arraySum = sumOf([1, 2, 3, 4, 5])

看起来很奇怪,但是在我的测试中起作用了。如果这给任何人带来意想不到的麻烦,请告诉我。Swift 似乎能够区分具有相同函数名的两个调用之间的区别。

此外,如果苹果像@manojid 的回答所暗示的那样更新了语言,使用这种方法,您只需更新这些函数即可。否则,您将不得不进行大量的重命名操作。

我知道这个回答不能准确回答你的问题,但是我觉得它没有什么价值。我也开始和斯威夫特一起玩,立刻遇到了一个类似的问题。我同意,对于你的问题来说,曼诺兹的回答更好一些,但同样的,我想到了另一个解决办法。我也更喜欢洛根。

在我的例子中,我只想传递一个数组:

func sumOf(numbers: Array<Int>) -> Int {
var sum = 0
for number in numbers {
sum += number
}
return sum
}


var someNums = [8,7,2,9,12]
sumOf(someNums)
sumOf([10, 15, 20])

只是想分享一下,以防有人和我想法一样。大多数情况下,我更喜欢像这样传递数组,但我不认为“迅速”。:)

您可以对函数进行强制转换:

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

我这样做(包装器 + 身份映射) :

func addBarButtonItems(types: REWEBarButtonItemType...) {
addBarButtonItems(types: types.map { $0 })
}


func addBarButtonItems(types: [REWEBarButtonItemType]) {
// actual implementation
}

Swift 5

这是一种具有 @dynamicCallable功能的方法,可以避免过载或 unsafeBitCast,但是您应该使用一个特定的 struct来调用:

@dynamicCallable
struct SumOf {
func dynamicallyCall(withArguments args: [Int]) -> Int {
return args.reduce(0, +)
}
}


let sum = SumOf()


// Use a dynamic method call.
sum(1, 2, 3) // 6


// Call the underlying method directly.
sum.dynamicallyCall(withArguments: [1, 2, 3]) // 6