1

我正在努力在 Swift 中构建一个名为 Node 的灵活数据结构,它本身不依赖于任何类型的内容。但是,Node 中的 Payload 数据被声明为以下符合 Equatable 协议的通用 Element 结构:

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

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

约束是 Element 必须绑定到可等价的类类型。我遇到的问题是包含此元素的节点。该节点将用于字典、数组或任何其他容器类型。这是我所拥有的:

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

当然,我得到了 AnyObject 不符合 Equatable 的错误。有什么方法可以将有效负载的声明限制为仅可等同的对象?此时,我不知道payload中可能存储了什么样的对象。

也刚刚意识到我需要在 Node 中的 == 函数中进行类检查,以确保两个 Node 有效负载兼容以进行比较——不需要它们。

想法?谢谢!

4

1 回答 1

2

为了约束payload到一个类型,即Equatable,您需要Node成为一个泛型类,以便它可以传递该约束。

您可以在类声明中指定约束:

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

然后在声明您的有效负载时,您可以将其元素类型设置为 T:

var payload: Element<T>

在测试代​​码时,我还必须使 Element 中的通用约束 T 符合 Equatable。完整代码供参考:

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
}

这将产生以下结果:

Node(_data: Element(data: 1)) == Node(_data: Element(data: 1)) // true
Node(_data: Element(data: 1)) == Node(_data: Element(data: 2)) // false
于 2016-09-13T01:29:05.130 回答