swift 3:func作为参数

swift 3:func作为参数,swift,parameters,func,Swift,Parameters,Func,我有几个功能: 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,

我有几个功能:

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测试,以及如何调用此测试func

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 { $0.value }).forEach {
                largestDouble = largestDouble < $0 ? $0 : largestDouble
            }
            return largestDouble
        }
    }
}

let largestValue = LargestDouble([
    FourParamDouble(data, -1, -1, -1),
    ...
    FourParamDouble(data, 100, 100, 100)
])
let result = largestValue.value

我还没有完全理解您的问题,但这可能暗示您的代码太复杂了。试着把它分成几个任务,并单独测试每个任务

基于协议的面向对象方法可能如下所示:

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 { $0.value }).forEach {
                largestDouble = largestDouble < $0 ? $0 : largestDouble
            }
            return largestDouble
        }
    }
}

let largestValue = LargestDouble([
    FourParamDouble(data, -1, -1, -1),
    ...
    FourParamDouble(data, 100, 100, 100)
])
let result = largestValue.value

正如@Rob Napier所述,在测试中实现类型安全性的唯一方法是为每个
x*
功能设置一个测试功能。但是,如果您可以更改
x*
函数,则有一种更简单的方法:声明一个接受可变数量参数的
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)
}

正如@Rob Napier所述,在测试中实现类型安全性的唯一方法是为每个
x*
功能设置一个测试功能。但是,如果您可以更改
x*
函数,则有一种更简单的方法:声明一个接受可变数量参数的
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)
}

您可以创建一个带有第三个
Int
的函数作为
可选
,然后在函数内部设置
条件,并按说明传递此函数参数(2或3),这在Swift中目前是不可能的。看起来您正在寻找类似于经常讨论的“splat”操作(在SE-0029中被删除)的东西,但即使这样,也很难想象您的函数是如何工作的。如果
params
的长度不正确怎么办?如何在编译时确定这一点?(这需要在编译时确定,或者打开Pandora的框来选择正确的分派,更不用说基本类型安全了。)我认为您需要采用另一种方法。使用泛型是最好的选择,同时使用var param,这样您就可以将任何数量的param传递给it@ShobhakarTiwari,这与泛型没有任何关系。也许您正在考虑使用
varargs
。您可以使用3rd
Int
创建一个函数作为
可选
,然后在内部设置
如果让
条件并按所述传递此函数参数(2或3),这在Swift中目前是不可能的。看起来您正在寻找类似于经常讨论的“splat”操作(在SE-0029中被删除)的东西,但即使这样,也很难想象您的函数是如何工作的。如果
params
的长度不正确怎么办?如何在编译时确定这一点?(这需要在编译时确定,或者打开Pandora的框来选择正确的分派,更不用说基本类型安全了。)我认为您需要采用另一种方法。使用泛型是最好的选择,同时使用var param,这样您就可以将任何数量的param传递给it@ShobhakarTiwari,这与泛型没有任何关系。也许你正在考虑
varargs
。如果你否决了某人,你应该告诉他/她为什么。如果你否决了某人,你应该告诉他/她为什么。是的,这就是解决办法!还有一件事是如何调用func测试?我尝试了:var opt_par=test(x1,数据,数组([-1…100])as![Int],数组([-1…100])as![Int])-但这不起作用。哪个部分不起作用?我可以看到一些问题。首先,Swift还不能将数组自动转换为可变长度的参数,所以不能传入
[-1..<100]
;相反,您必须传入每个数组元素,如
测试(x1,data,-1,0等)
。其次,我编写的
test
方法期望单个
Int
s作为可变长度参数,而不是
Int
s的数组。这有意义吗?问题在于[-1…100]作为参数。我想让testfunc做所有的事情并给出结果,所以我想把数组传递给它。我把它改为:func test(functionToTest:MaxFunction,data:[Double],pars:[Int]…)->[Double]{}。现在我通过数组(-1…100),一切正常。谢谢)是的,这就是解决这个问题的办法!还有一件事是如何调用func测试?我尝试了:var opt_par=test(x1,数据,数组([-1…100])as![Int],数组([-1…100])as![Int])-但这不起作用。哪个部分不起作用?我可以看到一些问题。首先,Swift还不能将数组自动转换为可变长度的参数,所以不能传入
[-1..<100]
;相反,您必须传入每个数组元素,如
测试(x1,data,-1,0等)
。其次,我编写的
test
方法期望单个
Int
s作为可变长度参数,而不是
Int
s的数组。这有意义吗?问题在于[-1…100]作为参数。我想让testfunc做所有的事情并给出结果,所以我想把数组传递给它。我把它改为:func test(functionToTest:MaxFunction,data:[Double],pars:[Int]…)->[Double]{}。现在我通过数组(-1…100),一切正常。(谢谢)