2016-04-29 38 views
2

我試圖做一些邏輯上看起來就像這樣 - 讓:斯威夫特:結合條件和邏輯或

if text == "" || let i = Int(text) where i < 2 { 
    // do something; don't care about the value of i 
} 

當然,這不是有效的條件 - 將價值i如果text == ""是持有的部分?但是,因爲我只對where條款中i的價值感興趣,所以我希望有一個很好的方法來達到相同的效果,即在任一條件成立時執行相同的閉包。我目前的解決方案是提取閉合,並從兩個單獨的if塊中調用它,但這看起來很毛茸茸。

回答

3

的相當於代碼的例子是:

if text == "" || Int(text) ?? 2 < 2 { 
    print("valid") 
    // do your previous "something 
} else { 
    print("invalid") 
} 

其產生

「」 - >有效
「1」 - >有效
「2」 - >無效
「abc」 - >無效

+2

呃, 「ABC」 打印'valid'因爲'零<2'。 – vacawama

+0

@vacawama正確:/修正了它,現在它不再那麼漂亮了。 – luk2302

+0

聰明!如果我需要更復雜的條件(我這樣做),那麼任何「無效」數字都會在「??」之後執行。 –

3

如果你正在做定期進行比較,您可以創建自己的運算符,以便將可選項和給定的閉包進行比較,以表示成功的條件。如果展開的值符合條件,它將返回true - 否則爲false。

例如:

infix operator ?& {precedence 130 } 
func ?&<T>(lhs: T?, @noescape rhs:(T)->Bool) -> Bool { 
    return lhs != nil ? rhs(lhs!) : false 
} 

... 

if text == "" || Int(text) ?& {$0 < 2} { 
    print("valid") 
} else { 
    print("invalid") 
} 

你也可以重載現有<運營商要做到這一點,但是這可能會影響現有的代碼依賴於nil小於非可選值。

func <<T:Comparable>(lhs: T?, rhs:T) -> Bool { 
    return lhs != nil ? (lhs! < rhs) : false 
} 

... 

if text == "" || Int(text) < 2 { 
    print("valid") 
} else { 
    print("invalid") 
} 
0

也許更「Swifty」的方式來處理可選值與map。本質上,map ping一個可選值給你一個你的閉包中的unwrapped值,然後你可以修改它來返回你需要的值。在關閉之外,您將收到修改後的值,如果原始可選爲零,則會收到零。

let optInt: Int? = 1 // or nil 
let incremented: Int? = optInt.map { $0 + 1 } 
// If optInt isn't nil, its incremented value is returned by map. 
// If it is nil, map just returns nil. 

所以要解決我的問題,我可以這樣做:

if text == "" || Int(text).map({$0 < 2}) ?? false { 
    // If text has an Int value, the map closure will return 
    // whether that value is less than 2. 
    // Else, map will return nil, which we coalesce to false. 
}