如果这是预期的行为,请试着绕过我的脑袋:
重构一些具有以下形式的代码:
let opt:Int? = 9
if let unwrapped = opt {
if unwrapped > 5 {
println("Yes")
// Prints Yes
}
}
我想删除嵌套的If语句。使用更紧凑的形式如此工作按预期工作:
if (opt ?? 0) > 5 {
println("Yes")
// Prints Yes
}
然而,我很惊讶与可选项的直接比较似乎也在条件中打开了可选项:
if opt > 5 {
println("Yes")
// Prints Yes
}
我用其他类型对此进行了测试,它们都具有相同的行为。显然,从Apple的文档中,检查了一个可选项是否等于nil,但是,我没想到它也会用包装的值进行评估。
我是否遗漏了某些内容(这是可以预料的)或者这是不受支持的选项行为?这似乎是将条件与选项组合起来的一种更简单的方法。
格雷格
答案 0 :(得分:3)
> operator
的一个定义是:
func ><T : _Comparable>(lhs: T?, rhs: T?) -> Bool
似乎编译器正在使用该版本的函数来比较Int?
和5
。我们可以直接使用swiftc
并要求它输出快速中间语言(SIL)来确认这一点:
swiftc -emit-silgen compare.swift
它输出半可读代码,如果我们深入研究它,我们可以看到它用于比较的函数调用:
// function_ref Swift.> infix <A : Swift._Comparable>(Swift.Optional<A>, Swift.Optional<A>) -> Swift.Bool
%17 = function_ref @_TFSsoi1gUSs11_Comparable__FTGSqQ__GSqQ___Sb : $@thin <τ_0_0 where τ_0_0 : _Comparable> (@in Optional<τ_0_0>, @in Optional<τ_0_0>) -> Bool // user: %28
这表明它确实使用>
运算符的版本需要两个Optional
。
但5
不是Optional
,那该怎么办?
好吧,如果我们更深入地了解SIL代码,我们可以看到如何。显然,Swift能够执行与可选绑定相反的操作,即将Optional
注入一个非可选值:
// function_ref Swift._injectValueIntoOptional <A>(A) -> Swift.Optional<A>
%25 = function_ref @_TFSs24_injectValueIntoOptionalU__FQ_GSqQ__ : $@thin <τ_0_0> (@out Optional<τ_0_0>, @in τ_0_0) -> () // user: %26
所以看起来正在发生的事情是我们基本上最终做了类似于(但不完全相同)的事情:
let opt: Int? = 9
if opt > (5 as Int?) {
println("Yes")
}
注意:即使我们执行以下操作,此功能仍然有效:
let opt: Int? = 9
let five: Int = 5
if opt > five {
println("Yes")
}
它仍会将five
注入Optional
,以便它可以执行比较。