如何创建可以替换参数的函数?

时间:2019-01-28 20:54:36

标签: swift

我有此代码:

let model = MyModel()

//1
guard let output = try? model.prediction (weigth:valueWeight) else {
  fatalError("Unexpected runtime error.")
}
//2
let length = output.length as Double

此代码使用不同的参数执行了数百次。

我想将其转换为函数。

但这是问题所在。查看// 1和// 2行。这些行具有此weigth参数,但是如果该代码是通用代码并在其他情况下重复使用,则在其他情况下该参数必须为depthlength

如何将其放在带有可替换这些字段的标题的函数中?

类似

func predict (model:MLModel, columnName:String, value:Double, target:String) -> Double {
  guard let output = try? model.prediction (columnName:value) else {
    fatalError("Unexpected runtime error.")
  }
  return output.target as Double
}

我的问题是columnName,它不是变量,而是列名。

Objective-C具有此NSSelectorFromString,其中可以通过字符串构建选择器。就是这种情况。我需要类似“ ParameterFromString”的内容。

这是我缩进调用函数的方式:

let predictLength = predict(model, "weigth", 10, "length")
let predictColor = predict(model2, "hue", 19, "color")

我希望第一行执行

guard let output = try? model.prediction (weigth:10) else {
  fatalError("Unexpected runtime error.")
}
let length = output.length as Double

第二行就像

guard let output = try? model2.prediction (hue:19) else {
  fatalError("Unexpected runtime error.")
}
//2
let color = output.color as Double

2 个答案:

答案 0 :(得分:2)

如果我理解正确的话,可以使用闭包。

typealias Predict = (MyModel, Int) throws -> Double

let predictHeigt: Predict = {m, h in
    let output = try m.prediction(height:h)
    return output.length as Double
}

let predictHue: Predict = {m, h in
    let output = try m.prediction(weight:h)
    return output.color as Double
}
//and so on for each type of prediction

func prediction(_ p: Predict, model:MyModel, value: Int) throws -> Double {
    return try p(model,value)
}

并像

一样使用它
let height = try prediction(predictHeigt, model: model, value: 10)
let hue = try prediction(predictHue, model: model2, value: 19)

答案 1 :(得分:1)

我添加了另一种方式来证明swift也可以以自己的方式使用NSSelectorFromString。 @objc很重要,在大多数情况下不能忽略。另外,objc不支持throws,所以不要使用它。

我认为这是符合您原始想法的确切方法。

            class MyModel: NSObject{

            @objc func prediction(_ : Any, weight: Double) -> Predict {
                let p =  Predict()
                p["length"] = weight
                print(p)
                return p
            }
            @objc  func prediction(_ : Any, hue : Double ) -> Predict {
                let p =  Predict()
                p["color"] = hue
                return p
            }
        }

        class Predict: NSObject{
             @objc var length: Double = 0.0
             @objc var color : Double = 0.0
             subscript (_ sub : String) -> Any? {
                get{
                    return value(forKey: sub)}
                set{
                    setValue(newValue, forKey: sub)
                }
            }
        }


        class TempTests: XCTestCase {

        func predict(_ model: MyModel, _ columnName : String, _ value:Double, _ target:String) throws -> Any? {
            let sel = Selector("prediction:"+"\(columnName)"+":")
            guard let output = model.perform(sel, with: value)?.takeUnretainedValue() as? Predict else {
                fatalError("Unexpected runtime error.")}
            return output[target]
        }

        func testExample() {


        let model = MyModel()
        let model2 = MyModel()

        do{
            let predictLength = try predict(model, "weight", 10, "length")
            let predictColor = try predict(model2, "hue", 19, "color")
            print(predictColor!)
            print(predictLength!)
        }
        catch{
            fatalError()
                }

            }

        }