For a circular doubly linked list this would be a simple node type:
class Node {
let value: Int
var pred : Node?
var succ : Node?
init(value: Int) {
self.value = value
}
}
Now let's assume that every node has always a predecessor and a successor, i.e. it is always a member of a circular doubly linked list (possibly consisting of this node alone). The pred/succ pointers are never nil, so I would like to define them as non-optionals, initialized to self. This naive approach does not compile:
class Node {
let value: Int
var pred : Node
var succ : Node
init(value: Int) {
self.value = value
self.pred = self // Variable 'self.pred' used before being initialized
self.succ = self // Variable 'self.succ' used before being initialized
}
}
I understand the error message, but I wonder what the best/Swiftiest solution would be.
If I leave them as optionals then I have always to unwrap the pointers, e.g.
self.pred!.succ = self.succ
self.succ!.pred = self.pred
when removing a node from the list. I can define them as implicitly unwrapped optionals:
class Node {
let value: Int
var pred : Node!
var succ : Node!
// ...
}
That solves most of the problems, but I still have to unwrap them when using intermediate variables (where the IUO becomes a strong optional):
let left = self.pred
left!.succ = self.succ
One could also define private stored IUO properties with public computed wrappers:
class Node {
let value: Int
private var _pred : Node!
private var _succ : Node!
var pred: Node {
get { return _pred }
set { _pred = newValue }
}
var succ: Node {
get { return _succ }
set { _succ = newValue }
}
init(value: Int) {
self.value = value
self._pred = self
self._succ = self
}
}
That seems to solve all problems, but is a lot of code for such a simple problem.
Are there other/better approaches? How would you define self-referential class types with pointers that cannot be nil?
Regards, Martin