2015-04-06 94 views
18

運行在操場下面的代碼片段給出了一個錯誤:比較可選的陣列

let a: [Int]? = [1,2] 
let b: [Int]? = [1,2] 
a == b // value of optional type '[Int]?' not unwrapped; did you mean to use '!' or '?'? 

雖然做一個「簡單」可選類型類似的工作原理:

var x: Int? = 10 
var y: Int? 
x == y // false 

什麼是背後的原因可選數組的第一種情況,不被允許?爲什麼不能Swift首先看到,如果任一方如果0​​(.None),然後如果他們不是,做實際的數組比較。

+0

你使用的是什麼版本的Swift?你的第二個案例給了我一個錯誤'變量'y'被初始化之前' – aganders3

+0

可能重複的[Swift錯誤比較兩個可選擇的數組](http://stackoverflow.com/questions/28830411/swift-error-comparing-雙陣列選項) – milo526

+0

對不起,我是從操場上輸入的。更正了這個問題。 –

回答

29

它適用於簡單的類型,是因爲有一種==一個版本是針對包含有Equatable類型自選定義:

func ==<T : Equatable>(lhs: T?, rhs: T?) -> Bool 

不過,雖然IntEquatableArray是不是(因爲它可能包含一些不可比較的東西 - 在這種情況下它可能會如何)。所有Equatable東西都有一個==運算符,但不是所有運算符==都是Equatable

你可以寫的==一個特殊情況版專爲含equatable類型可選的陣列:

func ==<T: Equatable>(lhs: [T]?, rhs: [T]?) -> Bool { 
    switch (lhs,rhs) { 
    case (.Some(let lhs), .Some(let rhs)): 
     return lhs == rhs 
    case (.None, .None): 
     return true 
    default: 
     return false 
    } 
} 

你也可以推廣爲覆蓋包含equatable元素的任何集合:

func ==<C: CollectionType where C.Generator.Element: Equatable> 
    (lhs: C?, rhs: C?) -> Bool { 
    switch (lhs,rhs) { 
    case (.Some(let lhs), .Some(let rhs)): 
     return lhs == rhs 
    case (.None, .None): 
     return true 
    default: 
     return false 
    } 
} 
+1

蘋果沒有直接實現它的任何原因嗎? –

+0

另外我遇到了你提出的第二個func的麻煩。比較[String]時?爲零,編譯器返回「對運算符=='的模糊使用」。我建議只使用第一個。 –

+0

但是爲什麼swift編譯器能夠解決這個問題:'Optional([1])== Optional([1])' – benrudhart

6

加入空速3速版答案:

func ==<T: Equatable>(lhs: [T]?, rhs: [T]?) -> Bool { 
    switch (lhs,rhs) { 
    case (.some(let lhs), .some(let rhs)): 
    return lhs == rhs 
    case (.none, .none): 
    return true 
    default: 
    return false 
    } 
} 

func ==<C: Collection where C.Iterator.Element: Equatable>(lhs: C?, rhs: C?) -> Bool { 
    switch (lhs,rhs) { 
    case (.some(let lhs), .some(let rhs)): 
    return lhs == rhs 
    case (.none, .none): 
    return true 
    default: 
    return false 
    } 
} 
0

最簡單的方法是不使用可選數組,並使用空數組([])而不是nil - 以防您不需要區分這兩種情況。

let a = [1,2] 
let b = [1,2] 
let c = [] 
a == b 
b != c 

它在我的情況下工作時,我正在編寫一個結構的Equatable擴展。我沒有使用屬性categories: [Category]?,而是將其更改爲categories: [Category],並將缺少的類別解析爲空數組([])。