What is the correct way to implement a stack in Go so that it will store structs?

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

What is the correct way to implement a stack in Go so that it will store structs?

问题

我正在尝试创建一个可以存储一系列Huffman树结构的堆栈。目前我正在使用在GitHub上找到的一个实现。

package util

type item struct {
    value interface{}
    next  *item
}

// Stack the implementation of stack
// this stack is not thread safe!
type Stack struct {
    top  *item
    size int
}
// Basic stack methods...

问题是,当我将Huffman树结构存储在堆栈中时,无法使用Huffman树的任何字段,例如左/右子节点。

package huffmantree

type HuffmanTree struct {
    freq   int
    value  byte
    isLeaf bool
    left   *HuffmanTree
    right  *HuffmanTree
    code   []bool
    depth  int
}

我应该如何在Go中实现一个堆栈,可以正确存储结构体并允许访问它们的字段?

编辑:
我尝试将interface{}部分替换为huffmantree.HuffmanTree(huffmantree结构体),并得到以下错误消息:

can't load package: import cycle not allowed
package github.com/inondle/huffman/util
    imports github.com/inondle/huffman/huffmantree
    imports github.com/inondle/huffman/util
import cycle not allowed

我猜测huffmantree类导入了util包,而堆栈必须导入huffmantree包,所以出现了某种冲突。有人知道出了什么问题吗?

英文:

I'm trying to make a stack that will store a series of Huffman Tree structs. Currently I'm using an implementation that I found on github.

package util

type item struct {
	value interface{}
	next  *item
}

//Stack the implementation of stack
//this stack is not thread safe!
type Stack struct {
	top  *item
	size int
}
// Basic stack methods...

The problem is that when I store my Huffman tree structs in the stack I can't use any of the fields of the Huffman tree such as left/right child.

package huffmantree
    
type HuffmanTree struct {
	freq   int
	value  byte
	isLeaf bool
	left   *HuffmanTree
	right  *HuffmanTree
	code   []bool
	depth  int
}

How am I supposed to implement a stack in Go which will correctly store structs and allow access to their fields?

Edit:
I tried replacing the interface {} part with huffmantree.HuffmanTree (huffmantree struct) and got this error message:

can't load package: import cycle not allowed
package github.com/inondle/huffman/util
	imports github.com/inondle/huffman/huffmantree
	imports github.com/inondle/huffman/util
import cycle not allowed

My guess would be that the huffmantree class imports the util package and the stack has to import the huffmantree package so there is some sort of conflict? Anyone know what went wrong?

答案1

得分: 7

在Go语言中实现栈的正确方法是简单地使用切片。

stack := []*HuffmanTree{}

你可以使用append将元素推入栈中,使用以下方式将元素弹出栈:

v, stack := stack[len(stack)-1], stack[:len(stack)-1]

如果你愿意,你可以将其封装成自己的类型,但是使用切片更容易理解。

type Stack []*HuffmanTree

func NewStack() *Stack {
    var s []*HuffmanTree
    return (*Stack)(&s)
}

func (s *Stack) Pop() *HuffmanTree {
    if len(*s) == 0 {
        return nil
    }
    v := (*s)[len(*s)-1]
    *s = (*s)[:len(*s)-1]
    return v
}

func (s *Stack) Push(h *HuffmanTree) {
    *s = append(*s, h)
}

正如icza所观察到的,如果栈的生命周期比HuffmanTree对象长,你可能希望将刚弹出的条目清零,以允许垃圾收集器收集无引用的对象。

英文:

The right way in go to implement a stack is simply to use a slice.

stack := []*HuffmanTree{}

You can push to the stack using append, and pop by writing:

v, stack := stack[len(stack)-1], stack[:len(stack)-1]

You could encapsulate it into its own type if you prefer, but a slice is easier to understand.

type Stack []*HuffmanTree{}

func NewStack() *Stack {
    var s []*HuffmanTree
    return (*Stack)(&s)
}

func (s *Stack) Pop() *HuffmanTree {
   if len(*s) == 0 {
      return nil
    }
    v = (*s)[len(*s)-1]
    *s = (*s)[:len(*s)-1]
    return v
}

func (s *Stack) Push(h *HuffmanTree) {
    *s = append(*s, h)
}

As icza observes, if the stacks live longer than the HuffmanTree objects, you may wish to zero the just-popped entry in your stack to allow the garbage collector to collect unreferenced objects.

huangapple
  • 本文由 发表于 2015年5月19日 09:29:52
  • 转载请务必保留本文链接:https://go.coder-hub.com/30315334.html
匿名

发表评论

匿名网友

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

确定