初始化和范围Swift

标签: Xcode ios Swift
发布时间: 2017/3/6 23:33:16
注意事项: 本文中文内容可能为机器翻译,如要查看英文原文请点击上面连接.

以下的代码不会被编译和 Swift 编译器会显示错误︰ "Variable 'firstVar' used before being initialized"

var firstVar: Double
var secondVar = 2.0

if 1 > 0 {
    firstVar = 2.0
}

print(firstVar)

在同一时间 Swift 编译器 (2.2) 已经没有问题,用下面的代码,它打印 "Hello, Stack Overflow" 。为 Swift 3.0,不出所料,下面的代码将显示错误消息。

var firstVar: Double
var secondVar = 2.0

if 1 > 0 {
    firstVar = 2.0
}

if secondVar > 1.0 && firstVar > 0 {
    print("Hello, stackoverflow!")
}

你能解释一下为什么第二个代码示例中的 if 语句的第二个条件计算结果为 true,编译器 ( Swift 2.2) 不抱怨 firstVar 正在初始化而它则是在第一个代码示例。

解决方法 1:

通过包装在一个闭包延迟表达式的计算︰ 的局限性 Swift 操场的上--飞"汇编"让这个错误的程序流传递无错误

rhs表达的 && ( = firstVar ) 自动包裹在一个闭包 (在这里︰ 使用 autoclosure ),这意味着的评价 firstVar 延迟 (懒洋洋地),这样你的例子将"编译"时使用的上飞编译 Swift 操场。我可以推测,即使前提条件将检查懒惰计算的正确性,只有在运行时,并不是在编译时,使用时 Swift 操场。

当试图在实际项目中一样,编译器不必抑制本身至快速飞上编译,并可以当场为它的是编译时错误︰

"错误︰ 变量 ' ... ' 初始化之前由一个闭包捕获"

即,上述不能编译,但不实际运行好适当的条件初始化的 firstVar 体内的 if 语句。请注意,这一事实, 1 > 0true 应该不影响事实这是编译时间错误,作为评价状态的 1 > 0一个运行时决定


详细信息

逻辑的二进制中缀运算符 '&&' 权利有侧 rhs 就是懒洋洋地,与实施@autoclosure

func &&(lhs: BooleanType, @autoclosure rhs: () -> BooleanType) -> Bool {
    return lhs.boolValue ? rhs().boolValue : false
}

语言参考-属性

autoclosure

此属性用于表达式的计算延迟的自动包装在一个闭包,不带任何参数的表达式。 将此属性应用于参数声明为一个函数或方法的类型,不带任何参数,并返回表达式的类型。声明与 autoclosure 属性意味着 noescape 时传递的可选属性参数,以及除外 escaping

我们可以显示您的例子更加明确地由下面的示例的行为︰

var foo: Double

/* use autoclosure to capture the argument in a closure */
func bar(@autoclosure arg: () -> Double) {
    print(arg())
}

/* or let the user explicitly supply the argument in a closure form */
func baz(arg: () -> Double) {
    print(arg())
}

if true {
    foo = 1.0
}

bar(foo)        // 1.0, OK in Playground, error when in a project
baz() { foo }   // 1.0, OK in Playground, error when in a project
官方微信
官方QQ群
31647020