Как выполнить метод для структуры, которая является полем для другой структуры

#go

#Вперед

Вопрос:

Я создал такие 2 структуры:

 type HostsFile struct {
    path    string
    masters string
    nodes   string
}

type AnsInstance struct {
    name      string
    url       string
    yamlPath  string
    user      string
    pass      string
    branch    string
    hostsFile *HostsFile
}
  

HostsFile у структуры есть такие методы:

 func (p *HostsFile) SetMasters(masters string) {
    p.masters = masters
}

func (p *HostsFile) SetNodes(nodes string) {
    p.nodes = nodes
}
  

и AnsInstance имеет такой, который использует методы из HostFile struct:

 func (p *AnsInstance) PrepInstExec(masters string, nodes string) {
    p.hostsFile.SetMasters(masters)
    p.hostsFile.SetNodes(nodes)
    p.hostsFile.GenerateHostsFile()
}
  

Когда я выполняю PrepInstExec таким образом:

 ansInstance.PrepInstExec("lalala,fafafaf", "bakuka,matata")
  

Я получаю ошибку:

 panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x18 pc=0x4ccba3]

goroutine 1 [running]:
card-installer/ansexec.(*HostsFile).SetMasters(...)
        /home/holo/go/src/card-installer/ansexec/ansexec.go:19
card-installer/ansexec.(*AnsInstance).PrepInstExec(0xc0000c5e90, 0x6d1a2c, 0xe, 0x6d15b9, 0xd)
        /home/holo/go/src/card-installer/ansexec/ansexec.go:145  0x53
main.main()
        /home/holo/go/src/card-installer/main.go:101  0x84e
exit status 2
  

Что я делаю не так? Есть ли возможность выполнять методы одной структуры, которая встроена в другую?

Редактировать:

Я создаю новый AnsInstance таким образом:

 func NewAnsInstance(name string, url string, path string) *AnsInstance {
    p := new(AnsInstance)
    p.name = name
    p.url = url
    p.yamlPath = path
    p.branch = "master"
    return p
}
  

Комментарии:

1. всегда выполняйте проверку ошибок

2. примечание: избегайте использования new в подобных случаях. Это скрывает тот факт, что вы создаете переменную-указатель, и это не позволяет вам инициализировать поля в одном операторе. используйте p := AnsInstance{} или p := amp;AnsInstance{} вместо

Ответ №1:

может быть, hostsFile равен нулю??

 func main() {
    ansInstance := NewAnsInstance("name", "url", "path")

    // add code and check hostsFile
    fmt.Printf("% vn", ansInstance)
}
  

Комментарии:

1. Я обновил сообщение с дополнительной информацией, не является ли «новым» создание всех полей структуры?

2. Если вы не понимаете, проверьте значение таким образом. обновление комментария.

3. Когда я добавил указатель на пустую переменную в методе NewAnsInstance, это помогло, но приведенное ниже решение, я думаю, для меня лучше — не использовать указатель в определении структуры.

Ответ №2:

Поскольку hostsFile *HostsFile имеет тип pointer, значение по умолчанию / ноль при создании экземпляра структуры будет равно нулю. Таким образом, вызов методов при nil приведет к панике.

Комментарии:

1. На этом я удалил тип указателя из структуры AnsInstance, и он работает. Спасибо.