I defined a protocol LLNodeType:
protocol LLNodeType {
typealias T
var firstNode: LLNode<T>? { get }
}
LLNode<T> is just a simple generic class, which contains a stored property of type N.
class LLNode<N> {
var content: N
...
}
To conform to the LLNodeType protocol I therefore extended LLNode as follows:
extension LLNode: LLNodeType {
typealias T = N
var firstNode: LLNode<T>? {
return self
}
}
I also defined a generic class LLLinkedList containing a few properties and functions using the generic type L:
class LLLinkedList<L> {
var rootNode: LLNode<L>?
...
}
I extended this class to conform to LLNodeType:
extension LLLinkedList: LLNodeType {
typealias T = L
var firstNode: LLNode<T>? {
return self.rootNode
}
}
I found a way of passing LLNodeType to methods of LLLinkedList as a regular type and used it on the append method:
func append<NT: LLNodeType>(nodeSequence: NT) {
let nodes = LLLinkedList(nodeSequence: nodeSequence)
...
}
As seen in the first statement of the append method, I have also defined an initializer for LLLinkedList, that takes a parameter nodeSequence of type LLNodeType:
convenience init<NT: LLNodeType where NT.T == L>(nodeSequence: NT) {
self.init()
self.rootNode = nodeSequence.firstNode
}
The initializer only takes a nodeSequence which conforms to LLNodeType, which is constrained though to use a type T equal to L.
The firstNode property of a nodeSequence conforming to these conditions should therefore return an LLNode<L>?.
Therefore the statement self.rootNode = nodeSequence.firstNode should be completely possible, since self.rootNode is of type LLNode<L>?.
When I try to compile the code, I get the error:
<stdin>:501:33: error: extra argument 'nodeSequence' in call
let nodes = LLLinkedList(nodeSequence: nodeSequence)
501:33 refers to the first statement of the append method.
How can there be an extra argument 'nodeSequence' if I defined the initializer with an argument called nodeSequence?
Here's a code sample containing only the parts relevant to the question: SwiftStub-Code
The problem is that your append function is not mandating the type of LLNodeType.T for the sequence you're appending:
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
}
}
You can resolve this by mandating you only append sequences of the same type as your
func append<NT: LLNodeType where NT.T == L>(nodeSequence: NT) {
// etc...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With