swift 3: func 作为参数
swift 3: func as argument
我有几个功能:
func x1(_ data: [Double], _ par1: Int, _ par2: Int) -> Double {
…
}
func x2(_ data: [Double], _ par1: Int, _ par2: Int, _ par3: Int) -> Double {
…
}
我想从 [-1 … 100]
测试它们作为 par1, par2, …
所以我必须调用:
x1(data, -1, -1)
x1(data, -1, 0)
...
x1(data, -1, 100)
x1(data, 0, -1)
…
x1(data, 100, 100)
同
func x2(data, -1, -1, -1) … x2(data, 100, 100, 100)
然后比较结果,找出 x1
或 x2
中最大的一个。我如何编写一个函数测试来调用另一个参数数量未知的函数(x1 有 3 个,x2 有 4 个),我该如何调用这个测试函数?
func test(testfunc: (_ data: [Double], _ par: Int…) -> Double, _ data: [Double], params: [Int]…) -> [Int] {
//?
return *optimal parameters , for example: [10, 57]
}
我还没有完全理解你的问题,但这可能暗示你的代码太复杂了。尝试将其拆分为多个任务并单独测试每个任务。
基于协议的面向对象方法可能如下所示:
protocol OODouble {
var value: Double { get }
}
final class ThreeParamDouble: OODouble {
private let data: [Double]
private let par1: Int
private let par2: Int
init(_ data: [Double], _ par1: Int, _ par2: Int) {
self.data = data
self.par1 = par1
self.par2 = par2
}
var value: Double {
get { /* calculate result (aka x1) here */ }
}
}
final class FourParamDouble: OODouble {
private let data: [Double]
private let par1: Int
private let par2: Int
private let par3: Int
init(_ data: [Double], _ par1: Int, _ par2: Int, _ par3: Int) {
self.data = data
self.par1 = par1
self.par2 = par2
self.par3 = par3
}
var value: Double {
get { /* calculate result (aka x2) here */ }
}
}
final class LargestDouble: OODouble {
private let doubles: [OODouble]
init(_ doubles: [OODouble]) {
self.doubles = doubles
}
var value: Double {
get {
var largestDouble: Double = 0
(doubles.map { [=10=].value }).forEach {
largestDouble = largestDouble < [=10=] ? [=10=] : largestDouble
}
return largestDouble
}
}
}
let largestValue = LargestDouble([
FourParamDouble(data, -1, -1, -1),
...
FourParamDouble(data, 100, 100, 100)
])
let result = largestValue.value
现在您可以独立于计算 x2 测试 x1 的计算,甚至可以独立测试 'find the largest one' ist。最后一个可以用伪造的协议实现进行测试:
final class OODoubleFake: OODouble {
init(_ value: Double) {
self.value = value
}
let value: Double
}
正如@Rob Napier 所说,在测试中实现类型安全的唯一方法是为每个 x*
函数设置一个测试函数。但是,如果您可以更改 x*
函数,则有一个 much 更简单的方法:声明一个 single x()
函数采用可变数量的参数:
func x(_ data: [Double], _ pars: Int...) -> Double {
// Loop through the variable number of pars like this:
for index in pars { ... }
}
现在您可以使用 任意 个参数调用它,因此:
let maxOf2 = x(data, -1, -1)
let maxOf7 = x(data, 100, 100, 100, 100, 100, 100, 100)
你的测试函数也同样简单:
func test(functionToTest: ([Double], Int...) -> (Double), data: [Double], pars: Int...) -> [Double] {
return functionToTest(data, pars)
}
使用 typealias
:
可能更容易阅读
typealias MaxFunction = ([Double], Int...) -> (Double)
func test(functionToTest: MaxFunction, data: [Double], pars: Int...) -> [Double] {
return functionToTest(data, pars)
}
我有几个功能:
func x1(_ data: [Double], _ par1: Int, _ par2: Int) -> Double {
…
}
func x2(_ data: [Double], _ par1: Int, _ par2: Int, _ par3: Int) -> Double {
…
}
我想从 [-1 … 100]
测试它们作为 par1, par2, …
所以我必须调用:
x1(data, -1, -1)
x1(data, -1, 0)
...
x1(data, -1, 100)
x1(data, 0, -1)
…
x1(data, 100, 100)
同
func x2(data, -1, -1, -1) … x2(data, 100, 100, 100)
然后比较结果,找出 x1
或 x2
中最大的一个。我如何编写一个函数测试来调用另一个参数数量未知的函数(x1 有 3 个,x2 有 4 个),我该如何调用这个测试函数?
func test(testfunc: (_ data: [Double], _ par: Int…) -> Double, _ data: [Double], params: [Int]…) -> [Int] {
//?
return *optimal parameters , for example: [10, 57]
}
我还没有完全理解你的问题,但这可能暗示你的代码太复杂了。尝试将其拆分为多个任务并单独测试每个任务。
基于协议的面向对象方法可能如下所示:
protocol OODouble {
var value: Double { get }
}
final class ThreeParamDouble: OODouble {
private let data: [Double]
private let par1: Int
private let par2: Int
init(_ data: [Double], _ par1: Int, _ par2: Int) {
self.data = data
self.par1 = par1
self.par2 = par2
}
var value: Double {
get { /* calculate result (aka x1) here */ }
}
}
final class FourParamDouble: OODouble {
private let data: [Double]
private let par1: Int
private let par2: Int
private let par3: Int
init(_ data: [Double], _ par1: Int, _ par2: Int, _ par3: Int) {
self.data = data
self.par1 = par1
self.par2 = par2
self.par3 = par3
}
var value: Double {
get { /* calculate result (aka x2) here */ }
}
}
final class LargestDouble: OODouble {
private let doubles: [OODouble]
init(_ doubles: [OODouble]) {
self.doubles = doubles
}
var value: Double {
get {
var largestDouble: Double = 0
(doubles.map { [=10=].value }).forEach {
largestDouble = largestDouble < [=10=] ? [=10=] : largestDouble
}
return largestDouble
}
}
}
let largestValue = LargestDouble([
FourParamDouble(data, -1, -1, -1),
...
FourParamDouble(data, 100, 100, 100)
])
let result = largestValue.value
现在您可以独立于计算 x2 测试 x1 的计算,甚至可以独立测试 'find the largest one' ist。最后一个可以用伪造的协议实现进行测试:
final class OODoubleFake: OODouble {
init(_ value: Double) {
self.value = value
}
let value: Double
}
正如@Rob Napier 所说,在测试中实现类型安全的唯一方法是为每个 x*
函数设置一个测试函数。但是,如果您可以更改 x*
函数,则有一个 much 更简单的方法:声明一个 single x()
函数采用可变数量的参数:
func x(_ data: [Double], _ pars: Int...) -> Double {
// Loop through the variable number of pars like this:
for index in pars { ... }
}
现在您可以使用 任意 个参数调用它,因此:
let maxOf2 = x(data, -1, -1)
let maxOf7 = x(data, 100, 100, 100, 100, 100, 100, 100)
你的测试函数也同样简单:
func test(functionToTest: ([Double], Int...) -> (Double), data: [Double], pars: Int...) -> [Double] {
return functionToTest(data, pars)
}
使用 typealias
:
typealias MaxFunction = ([Double], Int...) -> (Double)
func test(functionToTest: MaxFunction, data: [Double], pars: Int...) -> [Double] {
return functionToTest(data, pars)
}