swift - 'Constant captured by a closure before being initialized'错误是什么原因造成的

标签 swift swift2

在下面的类(class)中

class Foo {
   let _defaultValue = "N/A"
   let value: String 

   init (dict: NSDictionary) {
       self.value = dict["bar"] as? String! ?? _defaultValue
   }
}

编译器失败并显示消息 在初始化之前由闭包捕获的常量“self.value”

据我所知,没有运算符读取`self.value。该消息似乎有些令人困惑。

我无意中想到了一个解决方法。我应该说这让我更加困惑:

class Foo {
       let value: String 

       init (dict: NSDictionary) {
           let _defaultValue = "N/A"
           self.value = dict["bar"] as? String! ?? _defaultValue
       }
    }

声明 _defaultValue 并在构造函数中初始化它可以使代码编译。

如果有人能够解释为什么在第一种情况下会发生错误以及编译器在第二种情况下更高兴什么?

最佳答案

出现该错误消息的原因是 nil-coalescing 运算符 定义为

public func ??<T>(optional: T?, defaultValue: @autoclosure () throws -> T) rethrows -> T

并对第二个参数执行“自动关闭”(为了得到 短路行为)。所以

self.value = dict["bar"] as? String ?? _defaultValue

被编译器转换为

self.value = dict["bar"] as? String ?? { self._defaultValue }()

这里编译器会提示,因为 self 之前被捕获 正在完全初始化。 (错误信息略有不同 Swift 2 和 Swift 3 之间)。

可能的解决方法。您可以先将该属性分配给局部变量:

init(dict: NSDictionary){
    let defValue = _defaultValue
    self.value = dict["bar"] as? String! ?? defValue
}

或者您可以将其设为类的静态属性:

class Foo {
    static let _defaultValue = "N/A"
    let value: String

    init(dict: NSDictionary) {
        self.value = dict["bar"] as? String ?? Foo._defaultValue
    }
}

或者用 if 语句替换 ??:

class Foo {
    let _defaultValue = "N/A"
    let value: String

    init (dict: NSDictionary) {
        if let value = dict["bar"] as? String {
            self.value = value
        } else {
            self.value = _defaultValue
        }
    }
}

附录:相关资源:

引用错误报告:

Jordan Rose: This is true since && is implemented using @autoclosure, but it's certainly suboptimal.

关于swift - 'Constant captured by a closure before being initialized'错误是什么原因造成的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59449779/

相关文章:

ios - 不应该调用 Alamofire 4.0 RequestRetrier(_,retry,with,completion)

swift - 将我的代码变成更好的类似 Swift 的 FizzBu​​zz 响应答案

ios - 如何模拟 URL 结构?

swift - NSMenuItem 更新标题

shared-libraries - Xcode : relative path on embedded binaries

swift - 如何为我的新 .sks 文件创建一个 .swift 文件?

swift - 如何为泛型类型添加扩展?

ios - 如何将 ImageSliderViewController 转换为 Swift 2

swift - 使用 Swift 4 的简单网络请求

ios - 终止未捕获的异常 NSException - 连接到服务器后