drnzpd579935 2015-02-25 08:47
浏览 58
已采纳

Golang中LinkedList <T>的等效项是什么

In my use case, I would like to know how the following Java code would be implemented in Go

class TreeNode {
    public int data;
    public TreeNode left;
    public TreeNode right;
    public TreeNode(){}
}

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

I am able to import the container/list package and add an interface. But it is not allowing any generic object. Do I have to implement my own version of list with TreeNode struct?

I just need to know how LinkedList<T> would work in Go.

EDIT 1: To make it clear, I am adding the complete code here. I am trying to find the linked list of all nodes at each depth in a binary tree. I used two packages list and binary tree. You can find the source code for binarytree here and list here. list is same as container/list but I added few extra functions

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
    }
}

And the error is,

./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

EDIT 2: Based on JamesHenstridge's comment I edited from

current = current.PushFront(node.Left)

to

current.PushFront(node.Left)

And the issue resolved. But now I am getting interface conversion error,

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

goroutine 1 [running]:
  • 写回答

1条回答 默认 最新

  • dpql57753 2015-02-25 09:04
    关注

    Go doesn't support generic types (see FAQ question Why does Go not have generic types?).

    You have to use Type assertions to obtain the typed value you want.

    E.g. create your TreeNode type:

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

    And to iterate over a list containing TreeNode values:

    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
        }
    }
    

    If you assemble the list and you can be sure it only contains values of type TreeNode, you can omit the error check in the type assertion and it becomes like this:

    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)
    
    }
    

    Edit:

    The error you're getting:

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

    At line:

    current = current.PushFront(node.Left)
    

    The current variable is of type list.List, and the method current.PushFront() returns a value of type *list.Element. These are 2 different types, you can't assign a *Element to a variable that has a type of List.

    Edit 2:

    Your 2nd error:

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

    Is caused by the line:

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

    You try to assert that the value x.Value is of type int but it isn't! x.Value is of type *binarytree.Tree so the assertion will obviously fail.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥20 java在应用程序里获取不到扬声器设备
  • ¥15 echarts动画效果的问题,请帮我添加一个动画。不要机器人回答。
  • ¥60 许可证msc licensing软件报错显示已有相同版本软件,但是下一步显示无法读取日志目录。
  • ¥15 Attention is all you need 的代码运行
  • ¥15 一个服务器已经有一个系统了如果用usb再装一个系统,原来的系统会被覆盖掉吗
  • ¥15 使用esm_msa1_t12_100M_UR50S蛋白质语言模型进行零样本预测时,终端显示出了sequence handled的进度条,但是并不出结果就自动终止回到命令提示行了是怎么回事:
  • ¥15 前置放大电路与功率放大电路相连放大倍数出现问题
  • ¥80 部署运行web自动化项目
  • ¥15 腾讯云如何建立同一个项目中物模型之间的联系
  • ¥30 VMware 云桌面水印如何添加