英文:
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) {
// 设置next和prev指针
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
}
}
这显然是一个相当糟糕的实现。在这种情况下,我该怎么办呢?
英文:
I'd like to implement a linked list with nodes. Each node can be of a different type (Foo, Bar and Baz - will be 40-50 different nodes) and each type has common fields (prev, next, ...) and some node-specific fields.
I have a hard time to come up with a solution that looks reasonable. Now the question: what approach can I take to make this more elegant?
Here is my (dummy) 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)
}
and here is my implementation (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
}
}
This is obviously a pretty crappy implementation. What can I do in this case?
答案1
得分: 1
我不完全确定我理解你想做什么,但是这里有一些想法:
-
使用标准容器
-
将节点作为接口来包含你的“用户”数据:
type Node struct { next *Node Value interface{} }
这有点像在C中使用void*
来处理用户数据。
英文:
I am not entirely sure I understand what you are trying to do but here are a few ideas:
-
Use the standard container
-
Make the node contain your "user" data as an interface:
type Node struct { next *Node Value interface{} }
This is (somewhat) like doing it in C with a void*
to user data.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论