【问题标题】:Is this a bug in Xcode or a practice should be avoid by programmer?这是 Xcode 中的错误还是程序员应该避免的做法?
【发布时间】:2017-05-13 08:06:57
【问题描述】:

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

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 xcode protocol-extension


【解决方案1】:

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

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

【讨论】:

  • IBM Sandbox 显示“Swift 编译器报告了分段错误或类似错误。”如果我将实现添加到 FooImpl 或使扩展非递归,沙箱将接受代码。
  • 沙盒仅在您要求它运行代码时才说。此时您尝试执行无限递归,这会导致崩溃并导致错误。如果您将实现添加到 FooImpl,那么您将不再执行导致崩溃的无限递归调用的默认实现。
【解决方案2】:

您省略了实现的一个非常重要的部分。 如果你这样做了,你必须在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 sn-ps,唯一的区别是一个实际工作,另一个会崩溃。但这不是编译器应该担心的。

【讨论】:

    猜你喜欢
    • 2012-04-08
    • 1970-01-01
    • 2010-12-30
    • 2015-12-16
    • 1970-01-01
    • 2010-10-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多