如何比较Swift中的通用对象?

时间:2016-01-27 13:03:04

标签: swift generics

考虑以下简化代码段:

class Foo<T: Equatable> {
    var x: T
    init(_ x: T, _ y: T) {
        self.x = x
        if (x == y) {
            // do something
        }
    }
}

我希望这个课程适用于各种类似的T。理想情况下,如果T是一个对象,它将比较身份,并直接比较符合Equatable的所有其他内容 例如,上面的代码不适用于Array。如果我将Equatable更改为AnyObject而将==更改为===,那么它对Int不起作用。我该如何解决这个问题?我考虑过创建自己的协议但是我无法弄清楚如何为符合Equatable的所有类型实现它。

编辑:
我不知道它可以在Mac上运行,因为我在Linux上,当我尝试编译时

Foo<[Int]>([1, 2], [1, 2])

我收到以下错误:

error: type '[Int]' does not conform to protocol 'Equatable'
Foo<[Int]>([1, 2], [1, 2])
^

2 个答案:

答案 0 :(得分:1)

一个简单的解决方案是简单地为Equatable元素的数组添加另一个初始值设定项。

class Foo<T: Equatable> {
    init(_ x: T, _ y: T) {
        if (x == y) {
            print("Initialization by equal equatable types.")
        }
    }

    init(_ x: [T], _ y: [T]) {
        if (x == y) {
            print("Initialization by equal arrays of equatable types.")
        }
    }
}

let a = Foo<Int>(1, 1)
    /* Initialization by equal equatable types. */
let b = Foo<Int>([1, 2, 3], [1, 2, 3])
    /* Initialization by equal arrays of equatable types. */

答案 1 :(得分:-1)

根据你打算用Foo做什么,可能没有必要让它成为泛型类,而只是拥有通用的初始化器:

class Foo 
{
    init<T:Equatable>(_ x: T, _ y: T) 
    {
        if (x == y) 
        {
            // do something
        }
    }

    init<T:AnyObject>(_ x: T, _ y: T) 
    {
        if (x === y) 
        {
            // do something
        }
    }
}

// in Playground ...

class Bar { }

let C = Foo(3,4)  // no error

let O1 = Bar()
let O2 = Bar()

let D = Foo(O1,O2)  // no error