Массив реализации интерфейса и вызов дополнительных функций - PullRequest
0 голосов
/ 19 февраля 2020

У меня есть некоторое понятие служб в моем приложении. Интерфейс служб определяется следующим образом:

type Service interface {
    // Init and Start the Service
    Start() error
    // Start the Service
    // Stops the Service
    Stop() error        
}

Реализована пара типов с использованием этого интерфейса

type Service1 struct {  
}
func NewService1() *Service1 {
    return &MediaService{}
}
func (m *Service1) Start() error {
}
func (m *Service1) Stop() error {
}
func (m *Service1) Fn1() error {
}

и

type Service2 struct {  
    }
    func NewService2() *Service2 {
        return &MediaService{}
    }
    func (m *Service2) Start() error {
    }
    func (m *Service2) Stop() error {
    }
    func (m *Service2) Fn2() error {
    }

Хранение всего экземпляра в массиве

Services = make([]Service, 2)

    Services[0] = NewService1()
    Services[1] = NewService2()

Но я не могу вызвать дополнительную функцию, определенную в сервисах.

Services[0].Fn1 или Services[1].Fn2

1 Ответ

1 голос
/ 19 февраля 2020

Services = make([]Service, 2) означает, что у вас есть массив интерфейса Service

На самом деле не имеет значения, какие Service реализации вы добавляете, пока реализация выполняет контракт Service, именуемый Start() error и Stop() error

Когда вы получаете сервис из этого массива с:

Services[0]

во время компиляции, это если типа Service и поэтому Вы можете получить доступ только ко всем функциям Service.

Во время выполнения фактический тип, стоящий за Services[0], равен NewService1 или, возможно, другой, но это на самом деле не имеет значения, потому что вы указали массив Services типа Service и поэтому можете только получить доступ к этим функциям.

Если вы действительно хотите вызвать Fn1, вы должны сделать предположение, какой фактический тип находится за полями одного массива, и привести их:

Services[0].(*Service1).Fn1()


Если вы хотите избежать паники во время выполнения из-за недопустимых приведений (когда другой тип действительно доступен, как вы ожидаете), пожалуйста, посмотрите, как вы делаете утверждения типа https://golang.org/ref/spec#Type_assertions

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...