2017-09-18 7 views
0
assimilables

J'ai besoin pour récipient Tous lesEquatable articles dans PAS Generic classe (par exemple des classes d'interface utilisateur initiale de story-board). J'ai besoin comme çaclasse commune sur Swift

var items: [Equatable]? 

mais il ne fonctionne pas, Equatable besoin Générique. le problème qu'il n'existe pas de classe Equatable commune.


Ok - Aller au générique! Mais si je le fais

class Item<Value: Equatable>: Equatable { 
    var value: Value 
    init(_ value: Value) { 
     self.value = value 
    } 
    //Equatable 
    public static func ==(lhs: Item, rhs: Item) -> Bool { 
     return (lhs.value == rhs.value) 
    } 
} 

alors je serai obligé de spécifier le type dans ma classe non-Générique-UI. Comme cette

var items: [Item<WhatShouldBeHere?>]? 

mais encore une fois, nous arrivons au problème qu'il n'y a pas existe commune Equatable classe


Toutes les solutions pour conteneur pour tous assimilables?

+0

connexes: [Opération sur un tableau de struct mise en œuvre assimilables] (https: //stackoverflow.com/questions/41298464/operation-on-an-array-of-structs-implementing-equatable) – Hamish

Répondre

3

Au lieu de types existentiels, vous devez utiliser une gomme de type:

public struct AnyEquatable: Equatable { 
    public let value: Any 
    private let equals: (Any) -> Bool 

    public init<E: Equatable>(_ value: E) { 
     self.value = value 
     self.equals = { ($0 as? E) == value } 
    } 

    public static func == (lhs: AnyEquatable, rhs: AnyEquatable) -> Bool { 
     return lhs.equals(rhs.value) || rhs.equals(lhs.value) 
    } 
} 

Exemple d'utilisation:

let items = [ 
    AnyEquatable(1), 
    AnyEquatable(1.23), 
    AnyEquatable(true), 
    AnyEquatable("some string") 
] 

let desired = "some string" 
let desiredAsAnyEquatable = AnyEquatable(desired) 
let desiredDescription = String(reflecting: desired) 

for item in items { 
    let itemDescription = String(reflecting: item.value) 
    let isEqualToDesired = item == desiredAsAnyEquatable 
    print("\(itemDescription) is \(isEqualToDesired ? "": "not ")equal to \(desiredDescription)") 
} 

sortie Exemple:

1 n'est pas égal à " une chaîne "

1,23 n'est pas égal à" certains stri ng »

vrai n'est pas égal à « une chaîne »

« une chaîne de caractères » est égal à « une chaîne »

+0

bonne idée créer une méthode égale en générique init !!! merci –

+0

Notez que vous devez appeler 'equals (_ :)' pour 'lhs' et' rhs' afin de préserver la symétrie lors de la comparaison d'une sous-classe avec une instance de superclasse. – Hamish

+0

@Hamish Bon, je n'avais pas considéré cela. donc 'lhs.equals (rhs.value) || rhs.equals (lhs.value) '? – Alexander