实现“通用”节点列表。

huangapple go评论82阅读模式
英文:

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.

huangapple
  • 本文由 发表于 2015年1月6日 18:49:43
  • 转载请务必保留本文链接:https://go.coder-hub.com/27797034.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定