我定义了一个协议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
符合LLNodeType
,T
虽然使用等于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
答案 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...