Всем, привет.
Начал осваивать go. Но наткнулся на непривычное, после Си, поведение.
Создаю хранилище структур с мапой и метод получения указателя на структуру из этого хранилища.
Я ожидаю, что меняя структуру по полученному указателю, будет меняться структура и в хранилище.
Но такое поведение не наблюдается, как будто GetItem возвращает не указатель на структуру, а его копию
Итак, код:
Если в хранилище в мапу сразу класть ссылки, то все работает как задумано
Но меня не покидает ощущение, что и в первом варианте можно сделать по-человечески (в частности, переделать функцию GeItem) и вот эта пляска с указателями во втором варианте избыточна. Просто я чего-то не понимаю.
Начал осваивать go. Но наткнулся на непривычное, после Си, поведение.
Создаю хранилище структур с мапой и метод получения указателя на структуру из этого хранилища.
Я ожидаю, что меняя структуру по полученному указателю, будет меняться структура и в хранилище.
Но такое поведение не наблюдается, как будто GetItem возвращает не указатель на структуру, а его копию
Итак, код:
Кликните здесь для просмотра всего текста
:
package main
//структура
type ItemStruct struct {
State int
}
//хранилище структур
type Storage struct {
items map[int]ItemStruct
}
//создает хранилище структур
func NewStorage() *Storage {
res := Storage{
items: make(map[int]ItemStruct),
}
res.items[1] = ItemStruct{State: 1}
res.items[2] = ItemStruct{State: 2}
return &res
}
//возвращает указатель на структуру по id
func (s Storage) GetItem(id int) *ItemStruct {
res, ok := s.items[id]
if !ok {
return nil
}
return &res
}
func main() {
storage := NewStorage()
item := storage.GetItem(1)
item.State = 11
//вот на этом месте item.State == 11, а storage.items[1].state по прежнему равно 1
}
Если в хранилище в мапу сразу класть ссылки, то все работает как задумано
Кликните здесь для просмотра всего текста
:
package main
//структура
type ItemStruct struct {
State int
}
//хранилище структур
type Storage struct {
items map[int]*ItemStruct
}
//создает хранилище структур
func NewStorage() *Storage {
res := Storage{
items: make(map[int]*ItemStruct),
}
res.items[1] = &ItemStruct{State: 1}
res.items[2] = &ItemStruct{State: 2}
return &res
}
//возвращает указатель на структуру по id
func (s Storage) GetItem(id int) *ItemStruct {
res, ok := s.items[id]
if !ok {
return nil
}
return res
}
func main() {
storage := NewStorage()
item := storage.GetItem(1)
item.State = 11
}
Но меня не покидает ощущение, что и в первом варианте можно сделать по-человечески (в частности, переделать функцию GeItem) и вот эта пляска с указателями во втором варианте избыточна. Просто я чего-то не понимаю.