you don't need to mix generics and inheritance, one or the other should be
sufficient
type
BaseNode = ref object of RootObj
someEdge: BaseEdge
BaseEdge = ref object of RootObj
someNode: BaseNode
type
myNode = ref object of BaseNode
extraNodeField: int
myEdge = ref object of BaseEdge
extraEdgeField: int
var v = myNode(extraNodeField: 7)
v.someEdge = myEdge(extraEdgeField: 9)
echo v.repr
Run
> I could add a generic payload: T field instead (and put all extra fields
> there), but that means I would need to write node.payload.someExtraNodeField
> each time I want to access it (and also it would require extra memory).
you can write templates and procs to reduce boilerplate, overloading the `[]`
operator might be useful
containers don't take up more memory than their contents (modulo padding),
inheritable objects have an extra pointer.
type
Container[T] = object
payload: T
Base = object of RootObj
Inherited = object of Base
payload: int
let x = Container[int]()
let y = Inherited()
echo sizeof(x) #8
echo sizeof(y) #16
Run