Golang中的LinkedList <t>的等价物是什么</t>

时间:2015-02-25 08:47:25

标签: list struct go linked-list

在我的用例中,我想知道如何在Go

中实现以下Java代码
class TreeNode {
    public int data;
    public TreeNode left;
    public TreeNode right;
    public TreeNode(){}
}

LinkedList<TreeNode> treeList = new LinkedList<TreeNode>();

我可以导入容器/列表包并添加一个界面。但它不允许任何通用对象。我是否必须使用TreeNode结构实现我自己的列表版本?

我只需要知道LinkedList<T>在Go中的运作方式。

编辑1:为了说清楚,我在这里添加完整的代码。我试图找到二叉树中每个深度的所有节点的链表。我使用了两个包列表和二叉树。您可以找到binarytree here的源代码并列出here。 list与容器/列表相同,但我添加了一些额外的功能

package main
import (
    "fmt"
    "go/chapter02-linkedlists/list"
    "go/chapter04-treesandgraphs/binarytree"
)
func main() {

    inArr := []int{4, 5, 7, 8, 9}
    t1 := binarytree.NewMinimalHeightBST(inArr, 0, len(inArr)-1)
    binarytree.InOrderTraverse(t1)
    var nodeList []*list.List

    nodeList = getLevelbasedList(t1, 0)

    fmt.Println()
    for _, value := range nodeList {
        fmt.Print("[ ")
        for x := value.Front(); x != nil; x = x.Next() {
            fmt.Print(x.Value.(int), " ")
        }
        fmt.Println("]")
    }
}

func getLevelbasedList(root *binarytree.Tree, level int) []*list.List {
    if root == nil {
        return nil
    }
    var nodeList []*list.List
    parents := list.New()
    current := list.New()

    current.PushFront(root)

    for current.Len() > 0 {
        nodeList = append(nodeList, current)
        parents = current
        current = list.New()

        for x := current.Front(); x != nil; x = x.Next() {
            node := x.Value.(*binarytree.Tree)
            if node.Left != nil {
                current = current.PushFront(node.Left)
            }
            if node.Right != nil {
                current = current.PushFront(node.Right)
            }
        }
        return nodeList
    }
}

错误是,

./question4_4b.go:56: cannot use current.PushFront((interface {})(node.Left)) (type *list.Element) as type *list.List in assignment
./question4_4b.go:59: cannot use current.PushFront((interface {})(node.Right)) (type *list.Element) as type *list.List in assignment

编辑2 :基于JamesHenstridge的评论我来自

current = current.PushFront(node.Left)

current.PushFront(node.Left)

问题解决了。但现在我得到了接口转换错误,

[ panic: interface conversion: interface is *binarytree.Tree, not int

goroutine 1 [running]:

1 个答案:

答案 0 :(得分:8)

Go不支持通用类型(请参阅常见问题Why does Go not have generic types?)。

您必须使用Type assertions来获取所需的输入值。

E.g。创建TreeNode类型:

type TreeNode struct {
    Data  int
    Left  *TreeNode
    Right *TreeNode
}

迭代包含TreeNode值的列表:

l := list.New()
// Populate list

for e := l.Front(); e != nil; e = e.Next() {
    if tn, ok := e.Value.(TreeNode); ok {
        // do something with tn which is of type TreeNode
        fmt.Println(tn)
    } else {
        // e.Value is not of type TreeNode
    }
}

如果组装列表并且可以确定它只包含类型TreeNode的值,则可以省略类型断言中的错误检查,它变为如下所示:

for e := l.Front(); e != nil; e = e.Next() {
    // if e.Value would not be of type TreeNode, run-time panic would occur
    tn := e.Value.(TreeNode) // tn is of type TreeNode
    fmt.Println(tn)

}

修改

您获得的错误:

cannot use current.PushFront((interface {})(node.Left)) (type *list.Element)
    as type *list.List in assignment

在线:

current = current.PushFront(node.Left)

current变量属于list.List类型,方法current.PushFront()返回类型*list.Element的值。这些是两种不同的类型,您不能将*Element分配给类型为List的变量。

编辑2:

你的第二个错误:

panic: interface conversion: interface is *binarytree.Tree, not int

是由行引起的:

fmt.Print(x.Value.(int), " ")

您尝试声明值x.Value的类型为int,但它不是! x.Value的类型为*binarytree.Tree,因此断言显然会失败。