在泛型类中使用通用协议

时间:2015-01-30 18:58:44

标签: class generics swift constraints protocols

我定义了一个协议LLNodeType

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

LLNode<T>只是一个简单的泛型类,它包含N类型的存储属性。

class LLNode<N> {
    var content: N
    ...
}

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

extension LLNode: LLNodeType {
    typealias T = N

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

我还使用泛型类型LLLinkedList定义了包含一些属性和函数的泛型类L

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

我将此课程扩展为符合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定义了一个初始值设定项,它采用nodeSequence类型的参数LLNodeType

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

初始值设定项只需nodeSequence符合LLNodeTypeT虽然使用等于L的{​​{1}}类型,但仍受约束。

符合这些条件的firstNode nodeSequence属性应返回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方法的第一个陈述。

如果我使用名为extra argument 'nodeSequence'的参数定义初始化程序,怎么会有nodeSequence


此处的代码示例仅包含与问题相关的部分: SwiftStub-Code

1 个答案:

答案 0 :(得分:2)

问题在于,您的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...