Мои коллеги по ИТ-компании "Криптонит" пишут на 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 можно прочитать в этой статье.