Инициализация пустых интерфейсных переменных, где все члены являются функциями - PullRequest
0 голосов
/ 05 августа 2020

Я пытаюсь реализовать тип, который требует обратного вызова функции, и я застреваю с инициализацией переменной. Тип Terminal.New () требует типа Repeater, который имеет обратный вызов SetPacketFun c. Это определено в Terminal.New как таковое:

//Package dmr
type Repeater interface {
    Active() bool
    Close() error
    ListenAndServe() error
    Send(*Packet) error

    GetPacketFunc() PacketFunc
    SetPacketFunc(PacketFunc)
}
//Package terminal
func New(id uint32, call string, r dmr.Repeater) *Terminal {
    t := &Terminal{
        ID:       id,
        Call:     call,
        Repeater: r,
        slot:     []*Slot{NewSlot(), NewSlot(), NewSlot()},
        accept:   map[uint32]bool{id: true},
    }

    r.SetPacketFunc(t.handlePacket)
    return t
}

В моем коде я инициализирую пустую переменную типа Repeater: var r dmr.Repeater, а затем передаю ее в качестве аргумента в t := terminal.New(123,"test",r). Однако во время выполнения я получаю строку panic: runtime error: invalid memory address or nil pointer dereference at terminal.New в моем коде.

Как правильно определить тип Repeater, если все его члены являются функциями?

1 Ответ

1 голос
/ 05 августа 2020

Когда вы определяете переменную r, она инициализируется нулевым значением, которое для интерфейса равно nil. Поэтому, когда вы вызываете SetPacketFunc, получатель для этой функции равен нулю, что дает вам эту ошибку.

Вы должны передать конкретный репитер или интерфейс репитера, указывающий на конкретную реализацию репитера:

var r = SomeRepeaterImpl{}

func f() {
   term:=terminal.New(123,"test",&r)
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...