这是 Xcode 中的一个错误还是程序员应该避免的做法


首先

,我寻找一种通过为协议函数提供默认参数值来简化编码的方法。我在这里采用了解决方案,然后发现了它可能带来的一些致命子序列:

protocol Foo {
    func foo(_ a: Int)
}
extension Foo {
    func foo(_ a: Int = 4) {
        foo(a)
    }
}
struct FooImpl: Foo {
    // empty implementation
}
FooImpl().foo() // will go recursively forever and finally reach the stack limit

我还发现这段代码无法在IBM Swift Sandbox中编译,因此假设xcode编译器可能是罪魁祸首。

这看起来是编译器应该接受并执行的有效 Swift 代码。 它包含致命的无限递归是程序员的逻辑错误。

我在 IBM Swift Sandbox 中没有看到任何内容表明它处理代码比 Xcode 更好或不同。

您省略了实现中非常重要的部分。如果这样做,则必须在FooImpl中实现foo。如果你不实现它,你的代码基本上等同于

protocol Foo {
}
extension Foo {
    func foo(_ a: Int = 4) {
        foo(a)
    }
}
struct FooImpl: Foo {
}
FooImpl().foo()

这显然创造了一个无限循环。如果正确实现foo您将看到预期的行为:

protocol Foo {
    func foo(_ a: Int)
}
extension Foo {
    func foo(_ a: Int = 4) {
        foo(a)
    }
}
struct FooImpl: Foo {
    func foo(_ a: Int) {
        print(a)
    }
}
FooImpl().foo()

两者都是完全有效的 swift 片段,唯一的区别是一个实际有效,另一个会崩溃。但这不是编译器应该担心的。

最新更新