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 宇视监控服务器无法登录
  • ¥15 PADS Logic 原理图
  • ¥15 PADS Logic 图标
  • ¥15 电脑和power bi环境都是英文如何将日期层次结构转换成英文
  • ¥15 DruidDataSource一直closing
  • ¥20 气象站点数据求取中~
  • ¥15 如何获取APP内弹出的网址链接
  • ¥15 wifi 图标不见了 不知道怎么办 上不了网 变成小地球了
  • ¥50 STM32单片机传感器读取错误
  • ¥50 power BI 从Mysql服务器导入数据,但连接进去后显示表无数据