Что не так с этим следующим кодом, который выдает ошибку указателя

# #go #glide-golang

Вопрос:

Кто-нибудь может сказать мне, что не так с этим кодом?

 package main

import "fmt"

type Document struct{
    testString string
}

type Printer interface{
    Print(d *Document)
}

type Scanner interface{
    Scan(d *Document)
}

type MultiFunctionMachine struct{
     printer Printer
     scanner Scanner    
}

func (m *MultiFunctionMachine)Print(d *Document){       
    m.printer.Print(d)
}

func main(){
    doc:= Document{"test"}      
    multiMachine:= MultiFunctionMachine{}
    multiMachine.Print(amp;doc)
}
 

Я не мог понять, почему он продолжает выдавать следующую ошибку. Похоже, что-то не так с указателями.

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

     goroutine 1 [running]:
main.(*MultiFunctionMachine).Print(...)
    /Users/dmml/Documents/golang/udemyGoCourses/designPatternInGo/solidDesignPrinciples/interfaceSegrationPrinciple/main.go:85
main.main()
    /Users/dmml/Documents/golang/udemyGoCourses/designPatternInGo/solidDesignPrinciples/interfaceSegrationPrinciple/main.go:94  0x46
exit status 2*
 

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

1. m.printer это nil потому, что вы его не инициализировали.

2. Чего вы ожидаете MultiFunctionMachine{} от этого? Ожидаете ли вы, что он автоматически инициализирует все поля структуры до ненулевых значений? Если это так, то, как вы теперь знаете, в Go все работает не так.

Ответ №1:

структура вашей многофункциональной машины должна быть инициализирована конкретными реализациями как для интерфейсов принтера, так и для сканера, которые она содержит. Другими словами, вам нужно определить один или два типа (структуры или другие), которые реализуют интерфейсы сканирования(d *Документ) и печати(d *Документ) (т. е. имеют функции с той же подписью, что и эти интерфейсы). Затем назначьте эти конкретные типы полям интерфейса в многофункциональной машине. Только тогда можно будет использовать m:многофункциональную машину. Вы получаете ошибку разыменования указателя с нулем, поскольку эти поля не были инициализированы таким образом.