简体   繁体   中英

How to compare generic objects in Swift?

consider the following simplified snippet:

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

I would like this class to work for all kinds of T s that are somehow comparable. Ideally it would compare the identities if T is an object and directly compare everything else that conforms to Equatable .
The code above doesn't work for Array for example. If I change Equatable to AnyObject and == to === then it doesn't work for Int s. How do I solve this problem? I thought about creating my own protocol but then I couldn't figure out how to implement it for all types that conform to Equatable .

Edit:
I didn't know that it would work on the Mac because I am on Linux and when I try to compile

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

I get the following error:

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

A simple solution would be to simply add another initializer for arrays of Equatable elements.

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. */

Depending on what you intend to do with Foo, it may not be necessary to make it a generic class but rather just have generic initializers:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM