【问题标题】:Conversion of optional valued expressions to boolean将可选值表达式转换为布尔值
【发布时间】:2014-06-13 11:48:11
【问题描述】:

这感觉很基础。我提前道歉。但请考虑同一主题的以下四种变体:

var q : String? = nil

if let z : String? = q {
    println("q is non-nil")
} else {
    println("q is nil")
}

var zz : String? = nil
if (zz) {
    println("zz is not nil")
} else {
    println("zz is nil")
}

if let z : String? = nil {
    println("nil is non-nil")
} else {
    println("nil is nil")
}

/*
if (nil) {
    println("nil is non-nil")
} else {
    println("nil is nil")
}
*/

天真地,我认为这些都应该表现相同。但是输出是……

q is nil
zz is nil
nil is non-nil

如果我取消对最终表单的注释,我会得到...

Playground execution failed: error: <REPL>:57:5: error: type 'NilType' does not conform to protocol 'LogicValue'
if (nil) {

什么规则可以解释什么时候可选表达式可以被视为布尔值,nil 为假,{Somewhatever} 为真?为什么第三个 if 语句在语义上与其他语句相同时打印“nil is not nil”?为什么当绑定到变量或 let 表达式时,在 if 语句中 nil 可接受/可转换为 LogicValue,但在以文字形式呈现时不可接受?

【问题讨论】:

  • 第三个if 打印nil is non-nil 看起来很像编译器中的错误。您是否向 Apple 报告了此事?
  • (不……我想我一定错过了什么。这是我第一次玩 swift;如果有疑问,我认为我错了。)
  • 通常情况下,这是一个非常聪明的假设。 Beta 测试是该规则的一个显着例外;-)
  • 是否有任何关于 if let z : String? = q 应该做什么的文档,而不是 if let z = q,如果 q 不是 nil 则返回 true 并将 q 解包到 z 中?
  • 关于if nil ... if 语句需要一个布尔值。 nil 不是布尔值

标签: swift


【解决方案1】:

第三种情况的结果是有道理的。 “如果让”是测试分配是否成功。正常模式是:

var optional : String?
if let nonOptional : String = optional {
    // the optional could successfully be converted to a non-optional
}

您只是试图将 nil 分配给一个可选项,这确实是可能且有效的。因此,“let if”返回true。

对向下转换的分配做同样的事情也很常见

var any : AnyObject = "Hello"
if let string = any as? String {
     // Downcast to String was successful
}

最后,符合 LogicValue 的 Optional 类型允许在 if 语句中使用它。 NOT 可选返回nilnil 已测试。 nil 单独不能在 if 语句中使用,因为它没有实现 LogicValue 协议,也没有理由这样做。

【讨论】:

  • 谢谢。但是 nil 不需要符合 Optional 类型本身,那么如果 Optional 确实需要实现 LogicValue 协议以符合要求,那么它是否不需要实现 LogicValue 协议? (如果我遗漏了一些非常基本的东西,再次抱歉。)
  • @SteveWaldman nil 不需要符合 Optional,Optional 只需要定义一个赋值运算符就可以了
【解决方案2】:

您的Optional Binding 语法不正确。

应该是if let z = q {}

如果一定要添加类型,应该是:if let z:String = q

如果你这样做,

if let z : String = nil {
    println("nil is non-nil")
} else {
    println("nil is nil")
}

这行为正确并打印nil is nil

对于最后一种情况, 表达式必须是 boolif q 编译的原因是它会为您检查 nil 并且仍然返回一个布尔值。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多