在Swift中调用可选函数

6
我正在尝试找出一种通过编号动态调用方法的方法。以下是我正在做的简化版本。
class C {

    func a() {}
    func b() {}

    let f = [0: a, 1: b]

    func call(n: Int) {
        f[n]?()
    }
}

let c = C()

c.call(0)

当我在 Playground 中运行时,我得到了以下结果。
Playground execution failed: error: <REPL>:10:13: error: could not find an overload for 'subscript' that accepts the supplied arguments
    f[n]?()
    ~~~~^~~

然而如果我运行

func a() {}
func b() {}

let f = [0: a, 1: b]

f[0]?()

没有包含类时,可以直接使用,它的效果如预期。出了什么问题?
1个回答

12
这真的很有趣!我注意到,如果我将函数定义移到类外部但保持其他一切不变,你的第一行代码就能正常运行。从错误消息中,我得出结论,当在类内声明函数时,需要使用该类的实例来调用它们。当你只是在类内部调用 a() 时,编译器会自动将其解释为 self.a()。但是,当函数被存储在变量中(f[0]f[1]等)时,需要先传递一个 class C 的实例 (self)。这可以工作:
class C {

    func a() {println("in a")}
    func b() {println("in b")}

    let f = [0: a, 1: b]

    func call(n: Int) {
        a() // works because it's auto-translated to self.a()
        f[n]?(self)() // works because self is passed in manually
    }
}

let c = C()

c.call(0)

1
是的。f 实际上是类型为 Dictionary<Int, C -> () -> ()> 的字典。不过我仍然会使用可选链,并使用 f[n]?(self)() - Jean-Philippe Pellet
好的,我没有有意地切换那个。现在已经修复! - Dash
Dash。你是从哪里或者怎样得到这个信息的? - dellos
1
不错。这是一种非常有趣的方式来展示在Swift中实例方法是柯里化函数 - Milos

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接