Мои коллеги по ИТ-компании "Криптонит" пишут на Go. Я попросила их придумать ошибку — сможете её найти? Ждём в комментариях ваши варианты.
package main import "fmt" type User struct { name string meta map[string]string } func (u *User) SetMeta(key, value string) { u.meta[key] = value } func main() { u := &User{name: "Alice"} u.SetMeta("role", "admin") fmt.Println("Meta:", u.meta) }
.
.
.
ОСТОРОЖНО! ДАЛЬШЕ СПОЙЛЕР
В main() мы создаём указатель на User, но не инициализируем вложенную map[string]string (Meta)
Присвоение значения через u.Meta[key] = value, вызовет панику (panic: assignment to entry in nil map), потому что u.Meta всё ещё nil, и в Go нельзя присваивать значения в nil-мапу.
Одним из вариантов было бы добавить функцию NewUser(), создавать пользователя через нее, и сразу инициализировать мапу:
func NewUser(name string) *User { return &User{ name: name, meta: make(map[string]string), } } func main() { u := NewUser("Alice") u.SetMeta("role", "admin") fmt.Println("Meta:", u.meta) }
Второй вариант решения изменить SetMeta что бы инициализировать мапу, если она равна nil
func (u *User) SetMeta(key, value string) { if u.meta == nil { u.meta = make(map[string]string) } u.meta[key] = value
Ошибку и решение нам помог составить Алексей Косов, системный инженер департамента инфраструктуры в «Криптоните». Его материал про особенности, применение, плюсы и минусы Golang можно прочитать в этой статье.
