实施 "generic" 节点列表
Implement "generic" node list
我想用节点实现一个链表。每个节点可以是不同的类型(Foo、Bar 和 Baz - 将是 40-50 个不同的节点)并且每个类型都有公共字段(prev、next、...)和一些特定于节点的字段。
我很难想出一个看起来合理的解决方案。现在的问题是:我可以采取什么方法使它更优雅?
这是我的(假人)main.go
:
package main
import (
"fmt"
"node"
)
func main() {
a := node.NewFoo()
fmt.Println(a)
b := node.NewBar()
fmt.Println(b)
node.Append(a, b)
}
这是我的实现 (node.go
):
package node
type Node interface {
}
type FooNode struct {
prev Node
next Node
FieldSpecificToFoo int
}
type BarNode struct {
prev Node
next Node
FieldSpecificToBar int
}
type BazNode struct {
prev Node
next Node
FieldSpecificToBaz int
}
func NewFoo() *FooNode {
return &FooNode{}
}
func NewBar() *BarNode {
return &BarNode{}
}
func NewBaz() *BazNode {
return &BazNode{}
}
func Append(a, b Node) {
// set next and prev pointer
switch v := a.(type) {
case FooNode:
v.next = b
case BarNode:
v.next = b
case BazNode:
v.next = b
}
switch v := b.(type) {
case FooNode:
v.prev = a
case BarNode:
v.prev = a
case BazNode:
v.prev = a
}
}
这显然是一个非常糟糕的实现。在这种情况下我能做什么?
我不完全确定我明白你想做什么,但这里有一些想法:
- 使用standard container
使节点包含您的 "user" 数据作为接口:
type Node struct {
next *Node
Value interface{}
}
这(有点)类似于在 C 中对用户数据进行 void*
。
我想用节点实现一个链表。每个节点可以是不同的类型(Foo、Bar 和 Baz - 将是 40-50 个不同的节点)并且每个类型都有公共字段(prev、next、...)和一些特定于节点的字段。
我很难想出一个看起来合理的解决方案。现在的问题是:我可以采取什么方法使它更优雅?
这是我的(假人)main.go
:
package main
import (
"fmt"
"node"
)
func main() {
a := node.NewFoo()
fmt.Println(a)
b := node.NewBar()
fmt.Println(b)
node.Append(a, b)
}
这是我的实现 (node.go
):
package node
type Node interface {
}
type FooNode struct {
prev Node
next Node
FieldSpecificToFoo int
}
type BarNode struct {
prev Node
next Node
FieldSpecificToBar int
}
type BazNode struct {
prev Node
next Node
FieldSpecificToBaz int
}
func NewFoo() *FooNode {
return &FooNode{}
}
func NewBar() *BarNode {
return &BarNode{}
}
func NewBaz() *BazNode {
return &BazNode{}
}
func Append(a, b Node) {
// set next and prev pointer
switch v := a.(type) {
case FooNode:
v.next = b
case BarNode:
v.next = b
case BazNode:
v.next = b
}
switch v := b.(type) {
case FooNode:
v.prev = a
case BarNode:
v.prev = a
case BazNode:
v.prev = a
}
}
这显然是一个非常糟糕的实现。在这种情况下我能做什么?
我不完全确定我明白你想做什么,但这里有一些想法:
- 使用standard container
使节点包含您的 "user" 数据作为接口:
type Node struct { next *Node Value interface{} }
这(有点)类似于在 C 中对用户数据进行 void*
。