,我寻找一种通过为协议函数提供默认参数值来简化编码的方法。我在这里采用了解决方案,然后发现了它可能带来的一些致命子序列:
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 片段,唯一的区别是一个实际有效,另一个会崩溃。但这不是编译器应该担心的。