实施 "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*