2017-09-18 40 views
0

我需要容器不限EquatableNOT Generic類(從故事板初始示例UI類)。我需要這樣的普通Equatable類上夫特

var items: [Equatable]? 

,但它不工作,Equatable需要通用。問題是沒有共同的Equatable類。


好的 - 去通用!但如果我這樣做

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) 
    } 
} 

然後我會被迫在我的nonGeneric-UI類中指定類型。像這樣

var items: [Item<WhatShouldBeHere?>]? 

但我們再次來到了問題,有沒有存在的一般Equatable


的任何解決方案,爲容器全部Equatable?

+0

相關:[操作實施Equatable結構的數組上](HTTPS: //sackoverflow.com/questions/41298464/operation-on-an-array-of-structs-implementing-equatable) – Hamish

回答

3

代替存在類型,需要使用一個類型橡皮擦:

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) 
    } 
} 

示例用法:

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)") 
} 

輸出示例:

1是不等於「一些字符串「

1.23不等於」一些stri NG」

真正是不等於‘一些字符串’

‘一些字符串’等於‘一些字符串’

+0

好主意在通用init中創建equals方法!!!謝謝 –

+0

注意你應該爲'lhs'和'rhs'調用'equals(_ :)',以便在將子類與超類實例進行比較時保持對稱性。 – Hamish

+0

@Hamish好的,我沒有考慮過。所以'lhs.equals(rhs.value)|| rhs.equals(lhs.value)'? – Alexander