如何使用闭包来按名称调用具有各种签名和返回类型的方法

时间:2014-06-15 17:17:47

标签: closures swift

我一直在与Swift中的类型层次结构作斗争。我得到了所有类型的运行时异常并编译错误,试图做一些花了我几分钟用Python编写的东西。有一次,我得到XCode 6在链接器中抛出异常并锁定我的机器垃圾和索引像疯了一样。在这一点上,我转向社区寻求帮助。

基本上我希望我可以设置一个通用调度程序来按名称调用方法。这是我试图运行的代码的骨架:

class CallbackDemo {

    var interface: CallbackInterface = CallbackInterface()

    func getString() -> String { return "0.1" }
    func getInt() -> Int { return 1 }
    func getIntMul(factor: Int) -> Int { return 2*factor }
    func getVoid() {}

    init() {
        interface.callbacks = [ "getString": getString,
            "getVoid": getVoid,
            "getInt": getInt,
            "getMul": {(factor:Int) -> Int in return factor * 10 }
        ]

        if let result = self.interface.call("getString") {
            println("%s", result)
        }

    }
}

class CallbackInterface {
    typealias GenericSignature = (Any...) -> Any?

    var callbacks: Dictionary<String, GenericSignature> = [:]

    func call(name: String, params: Any...) -> Any? {
        if let cb = callbacks[name] {
            return cb(params)
        }
        return nil
    }
}

程序没有编译(正如我所说的那样,确实会崩溃链接器)。然而,这段代码代表了我希望能够实现的:注册通用签名,使用与之关联的名称调用它们并返回一些东西(或什么都没有)。

AnyObject显然没有剪切它,因为我也返回Int。我没有通过params的方法的另一个问题是(Any?...)希望得到至少一个参数。这是它所指的自我第一个参数吗?我没有线索。我的印象是变量可以不采用params,它可以独立运行,但由于某些未知原因(至少对我而言)在这种情况下不起作用。

我希望有人可以对此有所了解。感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

您的功能签名不匹配,请尝试:

func getString(args:Any...) -> String? { return "0.1" }
func getInt(args:Any...) -> Int? { return 1 }
func getIntMul(args:Any...) -> Int? { return 2*(args[0] as Int) }
func getVoid(args:Any...) {}

init() {
    interface.callbacks = [
        "getString": getString,
        "getVoid": getVoid,
        "getInt": getInt,
        "getMul": {(args:Any...) -> Int? in return (args[0] as Int) * 10 }
    ]

    if let result = self.interface.call("getString") {
        println("%s", result)
    }

}

基本上你现在使用的函数签名表示将传递0或1个单个参数,但你的typealias表示将传递一个数组,因此存在不匹配,编译器变得不快乐

我也尝试将func返回作为非选项,但操场上崩溃了。我认为从长远来看应该没问题,但是游乐场和/或编译器仍有很多问题。