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 optionals.

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

Popular posts from this blog

xslt - DocBook 5 to PDF transform failing with error: "fo:flow" is missing child elements. Required content model: marker* -

mediawiki - How do I insert tables inside infoboxes on Wikia pages? -

Local Service User Logged into Windows -