Интерфейс с методом, у которого не работает параметр interface{}

#go

#Вперед

Вопрос:

Я пытаюсь реализовать некоторые интерфейсы в Go.

У меня есть интерфейс:

 type InterfaceA interface{
    read(interface{}) string
}
  

Затем у меня есть InterfaceB:

 type InterfaceB interface{
    fetch()
}
  

У меня есть функция:

 func Read(a InterfaceA) {}
  

У меня есть структура, которая удовлетворяет интерфейсу с помощью своих методов, но вместо того, чтобы иметь переменную «interface{}», она передается InterfaceB как таковая:

 type StructA struct {}

func (a *StructA) read(b InterfaceB) string {
    resp := b.fetch()
    return resp
}
  

Кажется, это работает для моих модульных тестов, но когда я импортирую пакет, я получаю сообщение об ошибке, в котором говорится, что InterfaceA реализован некорректно, поскольку ожидается «чтение (интерфейс {})», а не «чтение (InterfaceB)». Ошибка:

 StructA does not implement InterfaceA (wrong type for read method)
have read(InterfaceB) string
want read(interface {}) string
  

Причина, по которой я пытаюсь передать интерфейс функции read(), заключается в том, что я могу издеваться над методом «i.fetch ()», но все же протестировать остальную часть функции read().

Я также не могу передать методу чтения StructA параметр интерфейса (например, read(b interface{}) , потому что тогда у b не будет fetch() метода.

Я делаю это неправильно? Я думал, что это работает так, как работают мои модульные тесты. Я столкнулся с проблемой только при импорте пакета.

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

1. Вы можете определить InterfaceA метод read как принимающий аргумент типа InterfaceB вместо interface{} . Хотя, если вы планируете использовать эти типы в разных пакетах, вам придется экспортировать методы.

2. read(interface{}) string != read(b InterfaceB) string . Типы должны действительно совпадать, interface{} в интерфейсе не является шаблоном generics, который можно заменить случайным образом. Настройте его так, чтобы типы совпадали

3. read(queuehelp.InterfaceB) != read(interface{}) , типы функций инвариантны., Смотрите FAQ: golang.org/doc/faq#covariant_types

Ответ №1:

спасибо за комментарии. Мне удалось заставить это работать с помощью утверждений типа type. Более подробную информацию можно найти здесь: golang.org/ref/spec#Type_assertions