我正在阅读Apple的“Swift编程语言”指南,并遇到了以下问题。该书将sumation函数定义为:
func sumOf(numbers: Int...) -> Int {
var s = 0
for number in numbers {
s += number
}
return s
}
并包含一个“编写计算其参数平均值的函数”的实验,我试图重新使用sumOf来定义:
func averageOf(numbers: Int...) -> Float {
var sum = sumOf(numbers)
return Float(sum)/Float(numbers.count)
}
Xcode返回一个错误,调用sumOf(数字):“'[Int]'不能转换为'Int'” 忽略明显的零除问题,为什么可变参数在方法中丢失了它们的类型,是否有办法将variadic参数传递给sumOf函数?
答案 0 :(得分:4)
可变参数的工作方式是,调用者能够逐个传递任意数量的单个参数:
sumOf(1, 2, 3, 4)
它们作为数组出现在函数内部:
sumOf(numbers: Int…) {
// numbers is of type [Int]
// (you can see this by option-clicking numbers in Xcode)
}
这样函数实现者可以告诉它有多少,循环它们等等。
但这意味着你不能使用另一个函数的variadic参数调用一个可变参数函数。 sumOf
函数需要类型为Int
的多个参数,例如1, 2, 3, 4
,但您传入的是[Int]
类型的数组参数,例如[1, 2, 3, 4]
。
这实际上是一种痛苦,因为Swift中没有“splat”功能 - 将数组转换为元组的能力。因此,您无法轻松地重复使用sumOf
功能。
一个解决方案是实现sumOf
两次:一次作为一个带数组的函数:
func sumOf(numbers: [Int]) -> Int {
// an alternative to the for loop
// you might want to try...
return reduce(numbers, 0, +)
}
曾作为一种变量函数:
func sumOf(numbers: Int...) -> Int {
// don’t reimplement sumOf, just
// call the array version
return sumOf(numbers)
}
然后你可以用任何一种方式调用它:
sumOf(1,2,3)
sumOf([1,2,3])
和Swift的函数重载决策将选择合适的版本。
现在你的averageOf
实现完全没问题,因为它可以使用sumOf
的数组版本。
(如果你想要额外的问题:尝试以相同的方式重载averageOf
,然后尝试编写sumOf
和averageOf
的版本,这些版本适用于使用泛型的任何整数类型:) / p>
答案 1 :(得分:2)
当您通过numbers
时,您传递了[Int]
类型的单个项目。可变参数签名需要的是它包装到数组中的一些单独的Int
。
同样,您可以撰写sumOf(1, 2, 3, 4)
但不能sumOf([1, 2, 3, 4])
。