swift - Surprising optional unwrapped in if conditional -
swift - Surprising optional unwrapped in if conditional -
trying wrap head around if expected behavior:
while refactoring code had form:
let opt:int? = 9 if allow unwrapped = opt { if unwrapped > 5 { println("yes") // prints yes } }
i wanted eliminate nested if statements. using more compact form such worked expected:
if (opt ?? 0) > 5 { println("yes") // prints yes }
yet surprised direct comparing optional seemed disclose optional in conditional:
if opt > 5 { println("yes") // prints yes }
i tested other types , had same behavior. apple's documentation, checking if optional equal nil discussed, yet, did not expect evaluate wrapped value.
did miss (and expected) or unsupported behavior of optionals? sure seems much easier way combine conditionals optionals.
greg
one of definitions of > operator
is:
func ><t : _comparable>(lhs: t?, rhs: t?) -> bool
it seems compiler using version of function compare int?
5
. can confirm using swiftc
straight , asking output swift intermediate language (sil):
swiftc -emit-silgen compare.swift
it outputs semi-readable code and, if dig through it, can see function phone call it's using comparison:
// 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 τ_0_0 : _comparable> (@in optional<τ_0_0>, @in optional<τ_0_0>) -> bool // user: %28
which shows indeed using version of >
operator takes 2 optional
s.
but 5
isn't optional
, how working?
well, if little deeper in sil code, can see how. apparently, swift has ability sort of opposite of optional binding inject non-optional value in optional
one:
// 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
so seems happening end doing similar (but not like) this:
let opt: int? = 9 if opt > (5 int?) { println("yes") }
note: works if like:
let opt: int? = 9 allow five: int = 5 if opt > 5 { println("yes") }
it'll still inject five
in optional
can perform comparison.
swift
Comments
Post a Comment