dongtang3155 2016-08-18 01:00
浏览 67
已采纳

golang附加到结构内部的一个切片

I'm trying to understand how to manipulate data structures in Go, and its approach to pointers (with copies or references).

my code is on Go Playground, here: https://play.golang.org/p/j_06RS5Xcz

I made up a map of slices of a struct that also has a slice of other thing inside.

here:

type Item struct {
    Name        string
    Description string
}

type Entity struct {
    Base   Item
    Others []Item
}

var database map[int][]Entity

func main() {
    database = make(map[int][]Entity)
    database[1] = []Entity{}

    e1 := Entity{}
    e1.Base = Item{"A", "aaa"}
    e1.Others = []Item{}

    database[1] = append(database[1], e1)

    // later, I want to add other items to my entity
    e1.Others = append(e1.Others, Item{"B", "bbb"})

    // other items field is empty
    fmt.Println(database)
}

// prints: map[1:[{{A aaa} []}]]

I want to append the Others items later in my program. it seems that I must use pointers to solve this, but I don't know how.

should my Entity be like this?

type Entity struct {
    Base   Item
    Others *[]Item
}

and if so, how should I append items to it? like this?

*e1.Others = append(*e1.Others, Item{"B", "bbb"})

.

.

.

if there is room for another question... it is also not clear to me if I 'must' do: database[1] = []Entity{} before database[1] = append(database[1], e1) or I could just append in this case. I tried the same on e1.Others = []Item{} but it didn't produced the same effect to append (I know that this is my misunderstanding, not a Go's fault).

thanks in advance :)

  • 写回答

1条回答 默认 最新

  • dtfbj24048 2016-08-18 01:16
    关注

    In your current code, you have two objects of type Entity. One is named e1, the other is named database[1]. These two objects are completely independent, since they are structs. Therefore, when you change one of them, it will not affect the other. (Small exception: some changes to the Items field will be shared, but not all.)

    If you want to first add the entity to the map and later modify it, you should use a map of pointers, map[int][]*Entity. Then, instead of Entity{}, you should create a pointer to an entity, with e1 := &Entity{}, and then the program will work. The changes to e1.Others will also affect database[1].Others, since these two variables now point to the same object.

    But the print statement will be different. Instead of printing the struct, it will only print a pointer value. To fix this, add a String method:

    func (e *Entity) String() string { return fmt.Sprint(*e) }
    

    See https://play.golang.org/p/edU7E5Gnjw, where I also removed the needless empty slices. It is perfectly ok to append to a nil slice.

    For further reading, I suggest http://research.swtch.com/godata, which will answer the questions that you currently have.

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

报告相同问题?

悬赏问题

  • ¥15 metadata提取的PDF元数据,如何转换为一个Excel
  • ¥15 关于arduino编程toCharArray()函数的使用
  • ¥100 vc++混合CEF采用CLR方式编译报错
  • ¥15 coze 的插件输入飞书多维表格 app_token 后一直显示错误,如何解决?
  • ¥15 vite+vue3+plyr播放本地public文件夹下视频无法加载
  • ¥15 c#逐行读取txt文本,但是每一行里面数据之间空格数量不同
  • ¥50 如何openEuler 22.03上安装配置drbd
  • ¥20 ING91680C BLE5.3 芯片怎么实现串口收发数据
  • ¥15 无线连接树莓派,无法执行update,如何解决?(相关搜索:软件下载)
  • ¥15 Windows11, backspace, enter, space键失灵