在通用 类 中使用通用协议

Using generic protocols in generic classes

我定义了一个协议LLNodeType:

protocol LLNodeType {
    typealias T
    var firstNode: LLNode<T>? { get }
}

LLNode<T> 只是一个简单的泛型 class,它包含一个 N.

类型的存储 属性
class LLNode<N> {
    var content: N
    ...
}

为了符合 LLNodeType 协议,我扩展了 LLNode 如下:

extension LLNode: LLNodeType {
    typealias T = N

    var firstNode: LLNode<T>? {
        return self
    }
}

我还定义了一个泛型 class LLLinkedList,其中包含一些使用泛型类型的属性和函数 L:

class LLLinkedList<L> {
    var rootNode: LLNode<L>?
    ...
}

我扩展了这个 class 以符合 LLNodeType:

extension LLLinkedList: LLNodeType {
    typealias T = L

    var firstNode: LLNode<T>? {
         return self.rootNode
    }
}

我找到了一种将 LLNodeType 作为常规类型传递给 LLLinkedList 方法的方法,并将其用于 append 方法:

func append<NT: LLNodeType>(nodeSequence: NT) {
    let nodes = LLLinkedList(nodeSequence: nodeSequence) 
    ...
}

正如在 append 方法的第一条语句中所见,我还为 LLLinkedList 定义了一个初始化程序,它接受类型为 LLNodeType 的参数 nodeSequence

convenience init<NT: LLNodeType where NT.T == L>(nodeSequence: NT) {
    self.init()
    self.rootNode = nodeSequence.firstNode
}

初始化程序仅采用符合 LLNodeTypenodeSequence,尽管使用等于 L.

的类型 T 受到限制

一个nodeSequencefirstNode一个属性符合这些条件所以应该return一个LLNode<L>?.

因此语句 self.rootNode = nodeSequence.firstNode 应该是完全可能的,因为 self.rootNode 是类型 LLNode<L>?.


当我尝试编译代码时,出现错误:

<stdin>:501:33: error: extra argument 'nodeSequence' in call
let nodes = LLLinkedList(nodeSequence: nodeSequence)

501:33指的是append方法的第一条语句。

如果我用名为 nodeSequence 的参数定义初始值设定项,怎么会有 extra argument 'nodeSequence'


这是一个代码示例,仅包含与问题相关的部分: SwiftStub-Code

问题是您的 append 函数没有为您追加的序列指定 LLNodeType.T 的类型:

func append<NT: LLNodeType>(nodeSequence: NT) {
    // here, nodeSequence could be of a String, an Int, who knows...
    let nodes = LLLinkedList(nodeSequence: nodeSequence) 
    ...
    // but here you try to append it to the existing list...
    // what if it's not a list of the same type?
    if self.isEmpty {
        self.rootNode = nodes.rootNode
    } else {
    /// appends a node by pointing the last nodes pointer ('nextNode' property) to the new node
        self.lastNode!.nextNode = nodes.rootNode
    }
}

您可以通过强制您仅附加与您的

相同类型的序列来解决此问题
func append<NT: LLNodeType where NT.T == L>(nodeSequence: NT) {
    // etc...