2015-03-03 56 views
4

我得到編譯錯誤在未來斯威夫特代碼斯威夫特誤差比較自選

var x:Array<Int?> = [1,2] 
var y:Array<Int?> = [1,2] 
if x == y { // Error 
} 

如果兩個數組都是Array<Int>它工作正常,但如果其中至少有一個是可選的,它拋出一個的兩個數組像下一個錯誤:

二元運算符 '==' 不能被應用到兩個操作數Array<Int?>

我幾個月前提交了一個錯誤報告,但我沒有回答。它仍然發生在Swift 1.2中。

這是怎麼發生的?

+2

Int?不是可以是'nil'的Int,它是可選的,當不是'nil'時可以是Int。那麼,Int和Int?是不能比較的不同類型。 – sasquatch 2015-03-03 11:22:11

+0

我也在幾個月前提交了Swift的幾個bug,也沒有反饋。我做了一個計算,蘋果每天獲得大約9500個有關雷達的bug報告。所以他們可能會工作(高)... – 2015-03-03 11:27:38

+0

@sasquatch你說的是真實的,但不是真正的根本原因。這裏沒有非選擇權,問題是缺乏可選擇的可選項。 – 2015-03-03 11:38:07

回答

8

這裏的問題是區分具有==運算符的東西,而不是某些「可相等」的東西。

兩個OptionalArray==操作,當它們包含的內容是equatable的作品:

// if T is equatable, you can compare each entry for equality 
func ==<T : Equatable>(lhs: [T], rhs: [T]) -> Bool 
// if T is equatable, you can compare the contents, if any, for equality 
func ==<T : Equatable>(lhs: T?, rhs: T?) -> Bool 

let i: Int? = 1 
let j: Int = 1 
i == j   // fine, Int is Equatable 
["a","b"] == ["a","b"] // and so is String 

但他們自己不符合Equatable。這是有道理的,因爲你可以在它們內部放置一個不相等的類型。但結果是,如果一個數組包含一個不可分類的類型,那麼==將不起作用。因爲可選項不是Equatable,所以在數組中放入可選項時就是這種情況。

你會得到同樣的事情,如果你想比較數組的數組:

let a = [[1,2]] 
let b = [[1,2]] 
a == b // error: `==` can’t be applied to `[Array<Int>]` 

如果你想特殊的情況下,你可以寫==爲自選的陣列爲:

func ==<T: Equatable>(lhs: [T?], rhs: [T?]) -> Bool { 
    if lhs.count != rhs.count { return false } 
    for (l,r) in zip(lhs,rhs) { 
     if l != r { return false } 
    } 
    return true 
} 

對於反例,由於Set需要其內容是哈希的(並因此equatable),它可以 equatable:

let setarray: [Set<Int>] = [[1,2,3],[4,5,6]] 
setarray == [[1,2,3],[4,5,6]] // true 
+0

我很困惑:==你在這裏粘貼的第二個實現,是不是暗示,如果我有兩個類型爲[Int]的數組,比你可以比較它們?但實際上它失敗了,並迫使你拆開它們。 – 2015-03-03 11:42:40

+1

@DánielNagy'=='是可選項的'=='版本的簽名。但僅僅因爲optionals有一個'=='操作符,不會意味着它們是'Equatable'。爲了符合'Equatable',類型需要一個非限定的'=='運算符,而可選版本只適用於包含可比較類型的可選項(如果包含的類型不是可比較的,它將會執行什麼操作?)。不幸的是,我不能粘貼不存在的代碼來顯示這個:-) – 2015-03-03 11:51:29

+0

這正是我所錯過的。我認爲答案中的最後一個函數已經在Swift中實現了。謝謝! – sangonz 2015-03-03 11:58:16