2015-10-20 8 views
9

Qualcuno può darmi una buona ragione per cui questo non funziona:Perché equatable non definiti per gli array opzionali

let a: [Int]? = [1] 
let b: [Int]? = nil 
a == b 

Questa sarebbe la mia soluzione proposta (se poco elegante). Ma è banale, quindi mi sento come se mi mancasse una buona ragione per cui questo non è implementato.

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

    if let lhs = lhs, let rhs = rhs { 
     return lhs == rhs 
    } 
    else if let _ = lhs { 
     return false 
    } 
    else if let _ = rhs { 
     return false 
    } 

    return true 
} 
+0

Infatti valore opzionale è enum: 'enum OptionalValue {caso Nessuno caso Alcuni (T)}' che può essere 'Nessuno' o il tuo tipo, quando si assegna valore uguale a matrice opzionale restituisce maiuscole/minuscole non uguali Nessuno restituisce in caso di secondo erray di stial nessun tipo In effetti è diverso quando si fa 'a == b' –

risposta

16

Optional può essere paragonato solo se il tipo avvolto sottostante è equatable:

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

ora array possono essere rispetto se il tipo di elemento è equatable:

/// Returns true if these arrays contain the same elements. 
public func ==<Element : Equatable>(lhs: [Element], rhs: [Element]) -> Bool 

ma anche per tipi uguali T, Array<T>non conforme al protocollo Equatable.

Allo stato attuale, questo non è possibile in Swift, vedere ad esempio Why can't I make Array conform to Equatable? per una discussione nel forum degli sviluppatori Apple. Questo cambiamento con l'attuazione di SE-0143 Conditional conformances a Swift 4.

L'implementazione è corretto, ecco un possibile differente utilizzando switch/case con pattern matching:

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

    switch (lhs, rhs) { 
    case let (l?, r?) : // shortcut for (.Some(l), .Some(r)) 
     return l == r 
    case (.None, .None): 
     return true 
    default: 
     return false 
    } 
} 
+0

Ah, capisco, non mi ero reso conto che il motivo per cui avrei potuto farlo prima con 'Array's non opzionale era solo a causa della dichiarazione della funzione globale invece di un'estensione di 'Array' per conformarsi a' Equatable' dove gli elementi sono 'Equatable'. Cosa ne pensi della mia soluzione proposta e perché Apple non avrebbe incluso anche quella funzione globale? –

+1

@ScottH: vedere l'aggiornamento. Potrei solo speculare sulla tua ultima domanda, ma se la implementassi per gli array, allora che dire dei dizionari, degli insiemi, delle sequenze, ...? –

+0

È molto SECCO, questo è un punto valido. Anche se questo seguirebbe lo stesso schema che Apple ha scelto di fornire '==' per gli array non opzionali. Sembra essere l'opzione migliore finché non possiamo fare qualcosa come 'extension CollectionType: Equitable dove Element: Equatable {...}'. –

Problemi correlati