2015-03-03 3 views
4

я получаю ошибку в компиляции в следующем Swift кодаSwift ошибки сравнение двух массивов дополнительных опций

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? не является Int, который может быть «nil», он является необязательным, который может быть Int, если не «nil». Итак, Int и Int? являются разными типами, которые нельзя сравнивать. – sasquatch

+0

Я также подал несколько ошибок с Swift, также несколько месяцев назад, а также никаких отзывов. Я подсчитал, что Apple получает около 9500 сообщений об ошибках на радаре в день. Таким образом, они, вероятно, работают по (высоким) номерам ... –

+0

@sasquatch, что вы говорите, правда, но не является основной причиной. Здесь нет никаких необязательных вариантов, проблема заключается в отсутствии «Equatable» соответствия опциональных. –

ответ

8

Проблема здесь заключается в различии между тем, что имеет оператор ==, а что-то «равнозначное».

Оба Optional и Array имеют == оператор, который работает, когда то, что они содержат 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 требует, чтобы его содержимое, чтобы быть hashable (и, таким образом, equatable), он может быть equatable:

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

Я запутался: вторая реализация ==, которую вы вставили здесь, не подсказывает ли это, что если у меня есть два массива с типом [Int] ?, чем вы можете их сравнить? Но на самом деле это терпит неудачу и заставляет вас их разворачивать. –

+1

@ DánielNagy '==' является сигнатурой для версии '==' для optionals.Но только потому, что опции имеют оператор '==', не означает, что они 'Equatable'. Чтобы соответствовать «Equatable», типу нужен неквалифицированный оператор '==', тогда как дополнительная версия применяется только к опциям, которые содержат равнозначный тип (что бы он сделал, если содержащийся тип не был равнозначным?). К сожалению, я не могу вставить несуществующий код, чтобы показать это :-) –

+0

Это именно то, чего мне не хватало. Я предположил, что последняя функция в ответе уже реализована в Swift. Благодаря! – sangonz

Смежные вопросы