如何将自引用Swift协议用作泛型类的类型

时间:2018-10-28 05:30:46

标签: swift generics

我一直在尝试使用协议创建通用节点的链接列表。我知道那里有五万个链表实现。这是出于教育目的。我查看了SO的相关问题,并在swift.org上阅读了有关协议的所有信息。我在其他网站上读过一些有关高级用法的文章,但仍然找不到能解决我所遇到问题的东西。

这似乎是一个琐碎的问题;也许我只是在问正确的问题?这是简化的代码:

protocol LinkableNode: class {
    func getNextNode() -> LinkableNode?
}

class LinkedList<T: LinkableNode> {
    var head: T?

    func detach() {
        head = head!.getNextNode()  // The call to getNextNode() is the problem
    }
}

我接到cannot assign value of type 'LinkableNode?' to type 'T?'的电话时得到getNextNode()。我也希望head成为一个节点,我认为T: LinkableNode可以做到这一点,但显然不是。我已经根据发现的一些非常相似的示例尝试了所有在阳光下的排列,但是我陷入了困境。

1 个答案:

答案 0 :(得分:3)

func getNextNode() -> LinkableNode?

定义了一种方法,该方法返回符合LinkableNode some 类型的值, 但这不必与调用该方法的类型相同。

你想要的是

protocol LinkableNode: class {
    func getNextNode() -> Self?
}

这定义了一个方法,该方法返回与调用时相同类型的(可选)值,并使剩余的代码编译。

旁注::除非您想要将代码崩溃到空列表中,否则, 使用可选的链接而不是强制展开:

class LinkedList<T: LinkableNode> {
    var head: T?

    func detach() {
        head = head?.getNextNode()
    }
}