[英]How can I create a golang struct wrapping a container/list.List?
我正在摸索我的struct包含list.List vs * list.List之间的意外差异。 以下为什么不工作?
type listHolder struct {
id int
mylist list.List
}
func newListHolder(id int, text string) listHolder {
var newLH listHolder
newLH.mylist = *list.New()
newLH.id = id
newLH.mylist.PushBack(text)
return newLH
}
func (l *listHolder) pushBack(text string) {
l.mylist.PushBack(text)
}
func (l *listHolder) printAll() {
for temp := l.mylist.Front(); temp != nil; temp = temp.Next() {
fmt.Println(temp.Value)
}
}
func main() {
a := newListHolder(1, "first")
a.pushBack("second")
fmt.Printf("listHolder %d length %d Front()= %v, Back()=%v\n",
a.id, a.mylist.Len(), a.mylist.Front().Value, a.mylist.Back().Value)
a.printAll()
}
这将输出以下内容,显示长度符合预期,但Front()和Back()方法不起作用。
listHolder 1 length 2 Front()= `<nil>`, Back()=<nil>
<nil>
如果我将结构定义为
// Same thing with a pointer
type listHolderPtr struct {
id int
mylist *list.List
}
func newListHolderPtr(id int, text string) listHolderPtr {
var newLH listHolderPtr
newLH.mylist = list.New()
newLH.id = id
newLH.mylist.PushBack(text)
return newLH
}
它按预期工作,但当然,listHolder结构的任何副本都共享对同一列表的引用,这不是我想要的。 我需要能够复制周围的对象并获得内部列表的新副本。 那可能吗?
有关我正在尝试做的简单示例,请参阅https://play.golang.org/p/KCtTwuvaS1R 。 在真实的用例中,我将在一个复杂的嵌套循环中的一个listHolder片段中向后推并弹出每个listHolder的前面。
我认为@ JimB建议在将值推送到listHolder.mylist
时制作列表的本地副本可能是解决问题的一个很好的解决方案(给定,我理解正确的基础问题)。 我试图想出一个如下所示的实现:
package main
import (
"container/list"
"fmt"
)
type listHolder struct {
id int
mylist list.List
}
func newListHolder(id int) listHolder { // don't push back when constructing a new listHolder
var newLH listHolder
newLH.mylist = *list.New()
newLH.id = id
return newLH
}
func (l *listHolder) pushBack(text string) {
// create a temporary list to copy all old and the new value to
tmpList := list.New()
// copy all existing values from l.mylist
for e := l.mylist.Front(); e != nil; e = e.Next() {
fmt.Printf("pushing back '%v' from old list\n", e.Value)
tmpList.PushBack(e.Value)
}
// push back the new value
tmpList.PushBack(text)
// print the new tmpList for debugging purposes
for ele := tmpList.Front(); ele != nil; ele = ele.Next() {
fmt.Printf("creating new list element: %v\n", ele.Value)
}
// replace l.mylist with tmpList
l.mylist = *tmpList
// another version of this solution could be to return a new (i.e. copied)
// *listHolder with all the old values and the new 'text' value
}
func (l *listHolder) printAll() {
for temp := l.mylist.Front(); temp != nil; temp = temp.Next() {
fmt.Println(temp.Value)
}
}
func main() {
a := newListHolder(1)
a.pushBack("first") // push a value to a
a.pushBack("second") // push another value to a
fmt.Printf("listHolder %d length %d Front()=%v, Back()=%v\n",
a.id, a.mylist.Len(), a.mylist.Front().Value, a.mylist.Back().Value)
a.printAll()
}
此代码输出:
creating new list element: first // nothing to copy, only creating a new list element
pushing back 'first' from old list // copy element ...
creating new list element: first // ... from old list
creating new list element: second // and push new element to 'tmpList'
listHolder 1 length 2 Front()=first, Back()=second // print a summary
first // of the
second // new list
如果我有一些模拟数据,我可以做更多的测试/调试。 至少这段代码没有*list.List
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.