0

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

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 编译器可能是罪魁祸首。

4

2 回答 2

4

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

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

于 2017-05-13T08:17:18.390 回答
0

您省略了实现的一个非常重要的部分。如果你这样做,你必须fooFooImpl. 如果你不实现它,你的代码基本上相当于

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 片段,唯一的区别是一个实际工作,另一个会崩溃。但这不是编译器应该担心的。

于 2017-05-13T08:37:49.650 回答