在 The Swift Programming Language 中,它说:
函数还可以采用可变数量的参数,将它们收集到一个数组中。 func sumOf(numbers: Int...) -> Int { ... }
当我使用逗号分隔的数字列表 (`sumOf(1, 2, 3, 4) 调用这样的函数时,它们在函数内作为数组可用。
问题:如果我已经有一个要传递给此函数的数字数组怎么办?
let numbers = [1, 2, 3, 4]
sumOf(numbers)
这将失败并出现编译器错误,“找不到接受提供的参数的 '__conversion' 的重载”。有没有办法将现有数组转换为可以传递给可变参数函数的元素列表?
这是我发现的解决方法。我知道这不完全是你想要的,但它似乎正在工作。
第 1 步:使用数组而不是可变参数声明您想要的函数:
func sumOf(numbers: [Int]) -> Int {
var total = 0
for i in numbers {
total += i
}
return total
}
第 2 步:从您的可变参数函数中调用它:
func sumOf(numbers: Int...) -> Int {
return sumOf(numbers)
}
第 3 步:调用任何一种方式:
var variadicSum = sumOf(1, 2, 3, 4, 5)
var arraySum = sumOf([1, 2, 3, 4, 5])
这看起来很奇怪,但它在我的测试中有效。让我知道这是否会给任何人造成无法预料的问题。 Swift 似乎能够区分具有相同函数名称的两个调用之间的差异。
此外,如果Apple按照@manojid的回答建议更新语言,则使用此方法,您只需要更新这些功能。否则,您将不得不进行大量重命名。
您可以转换函数:
typealias Function = [Int] -> Int
let sumOfArray = unsafeBitCast(sumOf, Function.self)
sumOfArray([1, 2, 3])
func sumOf(foo numbers: Int..., bar: Bool) -> Int {};
需要 typealias Function = (foo: [Int], bar: Bool) -> Int;
unsafeBitCast
简单地将一种可调用类型转换为另一种。这在今天可能有效,但除非参考说明如此,否则下一版本的编译器可以在这里自由地做任何事情(编译器错误/崩溃/随机执行代码......)。查看 unsafeBitCast 上看起来很严肃的警告。
您可以像这样使用辅助函数:
func sumOf (numbers : [Int]) -> Int { return numbers.reduce(0, combine: +) }
func sumOf (numbers : Int...) -> Int { return sumOf (numbers) }
Int...
并且不能(轻松)更改?
apply
过程。我收集一些人称之为“喷溅”。
sumArray
是什么?
我这样做了(包装器+身份映射):
func addBarButtonItems(types: REWEBarButtonItemType...) {
addBarButtonItems(types: types.map { $0 })
}
func addBarButtonItems(types: [REWEBarButtonItemType]) {
// actual implementation
}
我知道这个回复没有回答你的确切问题,但我觉得它值得注意。我也开始使用 Swift 并立即遇到了类似的问题。我同意,Manojlds 的回答更适合您的问题,但同样,我想出了另一种解决方法。我也碰巧更喜欢洛根。
就我而言,我只想传递一个数组:
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])
只是想分享一下,以防其他人像我一样思考。大多数时候我更喜欢像这样传递数组,但我不认为“迅速”。 :)
斯威夫特 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
sumOf(...numbers)
print
这样简单的事情,我也能做到这一点!