2015-06-03 52 views
1

我想比較兩個對象(同一個類)並返回不爲零的對象。檢查兩個對象在Swift中是否爲零,ios xcode

你如何在swift中寫這樣的東西? :

func returnWhatIsNotNil(objA: SomeClass, objB: SomeClass) -> SomeClass { 
    if objA != nil && objB != nil { //error 
     //both are not nil 
     return nil 
    } 

    if objA == nil && objB != nil { // error 
     // objA is nil 
     return objB 
    } 

    if objA != nil && objB == nil { // error 
     // objB is nil 
     return objA 
    } 
} 

一個對象,

if let x = objA { 
    //objA is not nil 
} 

會做的工作,但我安靜不知道我會如何與兩個對象做到這一點。

+0

使用寫入的參數,objA和objB不能爲零。在執行任何代碼之前,調用會崩潰。他們必須是SomeClass類型的? – gnasher729

+0

請注意,您可以使用switch語句同時比較兩個項目。我發佈了一個後續接受的答案。 – vacawama

回答

3
class SomeObject { 

} 

func returnWhatIsNotNil(objA: SomeObject?, objB: SomeObject?) -> SomeObject? { 
    if let objA = objA where objB == nil { 
     return objA 
    } 
    if let objB = objB where objA == nil { 
     return objB 
    } 
    return nil 
} 
+0

從「objA:SomeObject,objB:SomeObject」更改爲「objA:SomeObject ?, objB:SomeObject?」讓我與零比較。謝謝 –

+1

我添加了一個使用switch語句來完成同樣事情的例子。 – vacawama

3

編輯:對不起,誤解您的原始問題。如果你想nil當兩者都是非零,那麼這是一個單線程:return objA.map { objB == nil ? $0 : nil } ?? objB。不過,@ LeoDabus使用if…let…where的版本看起來更易讀。


預編輯假設你想在第一時也不是零:

您要使用的未繳合併運算符,??。所以要從你的函數返回一個可選項,你只需要return objA ?? objB。請注意,您的所有輸入和輸出類型也必須是可選的。

通常情況下,您使用它來給出默認值,如果爲零,即"foo".toInt() ?? 0,如果非零,則展開該值,或者將其替換爲默認值(如果它爲零)。

但是,如果右側也是一個可選項,它將返回一個可選項,如果它不是零,則返回一個可選項,否則返回正確的一個,即使該項爲零​​。

let i: Int? = nil 
let j: Int? = nil 
let k: Int? = 42 

if let num = i ?? j { 
    fatalError("won't execute") 
} 

if let num = j ?? k { 
    assert(num == 42, "k will be chosen") 
} 
else { 
    fatalError("this would run if all 3 were nil") 
} 

的同時也要記住,你可以鏈??太:

let x = i ?? j ?? k ?? 0 // will result in an unwrapped 42 
+0

那麼,你如何檢查兩個對象是否爲零或不在一行? –

+0

'(i ?? j)== nil'如果你真的不想用'&&'來寫。但是你有可能想檢查_and_ unwrap,因此將它與'if let'結合使用是有用的。 –

+0

但是要從你的函數返回一個可選的,你只需要'return objA ?? objB' –

1

至於提到的零合併運算??可以使用。

這是你的函數的實現,注意你並沒有確定會發生什麼,當兩個objA和objB是非零

func returnWhatIsNotNil(objA: SomeClass?, objB: SomeClass?) -> SomeClass? { 
    return objA ?? objB 
} 
2

作爲後續行動,以@LeoDabus'接受的答案,您可以使用switch聲明也:

class SomeObject { 

} 

func returnWhatIsNotNil(objA: SomeObject?, objB: SomeObject?) -> SomeObject? { 
    switch (objA, objB) { 
    case (let a, nil): return a 
    case (nil, let b): return b 
    default: return nil 
    } 
} 
+0

這是一個不錯的解決方案。 – Caleb

0

雖然,一個字面翻譯斯威夫特在你的代碼是可能的,這是

func returnNotNil(num1: Int?, num2: Int?) -> Int? 
{ 
    if let x = num1 { 
     return x 
    } 
    else if let y = num2 
    { 
     return y 
    } 
    else 
    { 
     return nil 
    } 
} 

這裏的問題是,在斯威夫特,我們將不得不繼續返回類型爲可選的 - 所以一旦從函數返回,你會再次必須檢查返回值是不是nil,並解開。 恕我直言,一個合乎邏輯的翻譯是,(假設你不介意回任,當他們都不是零)

func returnNotNilOrAssert(num1: Int?, num2: Int?) -> Int 
{ 
    if let x = num1 { 
     return x 
    } 
    else if let y = num2 
    { 
     return y 
    } 
    else 
    { 
     assert(false, "Both nil") 
    } 

} 

是否要斷言,可能是一個實現選擇,你將不得不使。另一種方法是,如果你確定的話,其中一個將不是零,那麼你將函數的返回類型「隱式地解開」。我知道你想返回nil,當兩者都是零,但然後不得不檢查這個函數的返回值應該檢查兩個值,並返回不是零的那個,恕我直言,沒有多大意義,所以我試了一下這條路。

相關問題