简体   繁体   中英

Swift 2 Generic data structure not conforming to Equatable protocol

I am working on building a flexible data structure in Swift called Node that, by itself, is not tied to any type of content. However, the Payload data within the Node is declared as the following generic Element struct that conforms to the Equatable protocol:

public struct Element<T>: Equatable {
  var data: T;
}

public func ==<T:Equatable>(lhs: Element<T>, rhs: Element<T>) -> Bool {
    return lhs.data == rhs.data;
}

The constraint is that the Element has to be tied to an equatable class type. The problem I'm having is with the Node containing this Element. The Node would be used in a Dictionary, Array, or any other container type. Here is what I have:

public class Node: Equatable {

    var payload: Element<AnyObject>

    init(_data: Element<AnyObject>) {
        self.payload = _data
    }

}

public func ==(lhs: Node, rhs: Node) -> Bool {
    return lhs.payload == rhs.payload;
}

Of course, I'm getting the error that AnyObject does not conform to Equatable. Is there any way to constrain the declaration of the payload to only Objects that are equatable? At this point, I don't know what kind of objects may be stored in the payload.

Also just realized I need to put a class check in the == function in Node to make sure the two Node payloads are compatible to be compared--don't need them to be.

Thoughts? Thank you!

In order to constrain payload to a type that is Equatable , you'll need Node to be a generic class so that it can pass along that constraint.

You can specify the constraint in your class declaration:

public class Node<T: Equatable>: Equatable {...}

And then when declaring your payload you can set its Element type to just T:

var payload: Element<T>

When testing the code, I had to also make the generic constraint, T, in Element conform to Equatable. Entire code for reference:

public struct Element<T: Equatable>: Equatable {
    var data: T
}

public func ==<T:Equatable>(lhs: Element<T>, rhs: Element<T>) -> Bool {
    return lhs.data == rhs.data
}

public class Node<T: Equatable>: Equatable {
    var payload: Element<T>
    init(_data: Element<T>) {
        self.payload = _data
    }
}

public func ==<T: Equatable>(lhs: Node<T>, rhs: Node<T>) -> Bool {
    return lhs.payload == rhs.payload
}

This will produce the following results:

Node(_data: Element(data: 1)) == Node(_data: Element(data: 1)) // true
Node(_data: Element(data: 1)) == Node(_data: Element(data: 2)) // false

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