2016-08-23 5 views
-2

Я не уверен, что это должны быть два отдельных вопроса или один, но мне кажется, что один вопрос состоит из двух частей. Как следует использовать интерфейсы go? У меня есть две проблемы:интерфейс golang, который зависит от интерфейса

Методы интерфейсов имеют глобальную область видимости: если у меня есть интерфейс A и интерфейс B, которые реализуют один и тот же метод Foo, но с разными аргументами или типами возврата, я не могу реализовать их как на то же время из того же типа. Например, у меня есть метод GetBytes() в одном интерфейсе с типом возвращаемого типа [], а в другом ([] байт, ошибка). Как я должен преодолеть эту проблему?

Еще одна проблема, с которой я сталкиваюсь, - это когда я пытаюсь определить интерфейс say interface A, у которого есть метод, который возвращает интерфейс B, определенный в том же слое. Теперь, если я хочу создать объект, который реализует A, если я возвращаю struct, который реализует B, то он недостаточно умен, чтобы вывести, что этот метод реализует метод в A, и это заставляет меня создавать зависимость от B. Это, кажется, полностью побеждает точка пути работы интерфейсов на первом месте. Как я могу избежать этой проблемы?

, например, если у меня есть:

type B interface { 
    Bar() 
} 

type A interface { 
    Foo() B 
} 

для следующих структур:

type b_impl struct{} 

func (b b_impl) Bar() {} 

type a_impl struct{} 

Способ Foo

func (a a_impl) Foo() b_impl {} 

не удовлетворяет интерфейсу и мне нужно сделать это:

func (a a_impl) Foo() B {} 

, который создает зависимость от пакета, в котором объявлен B.

+0

«Как я должен преодолеть эту проблему?» Вы не можете, так как Go не поддерживает перегрузку метода. См. Https://golang.org/doc/faq#overloading. Я не понимаю ваш второй вопрос достаточно хорошо, чтобы попытаться ответить. Возможно, поможет пример кода. – smarx

+0

thanks @smarx - я отредактировал вопрос с более подробной информацией для второй части – gsf

+0

Я не думаю, что вы можете сделать что-нибудь еще о своей второй проблеме. – smarx

ответ

2

1-й вопрос: В go вам нужно создать разные имена функций, если вы хотите выполнять разные задачи. Давайте рассмотрим стандартную библиотеку в пакете strconv, как там все решено: https://golang.org/pkg/strconv/#pkg-index

Посмотрите на другое объявление функции добавления. Существуют функции для каждого другого типа.

Так что, если вы ожидаете FooInt Funtion ваш интерфейс должен быть также FooInter ...

второй вопрос: В качестве небольшого примера. Вам не нужно импортировать весь пакет io, если вы хотите использовать интерфейс io.Writer. Вполне нормально копировать декларацию Writer в ваш собственный пакет. Если вы сделаете это правильно, каждая реализация io.Writer автоматически реализует ваш собственный интерфейс Writer.

После прочтения других комментариев, может быть, у вас есть другая ситуация:

Допустим, есть пакет а и б с интерфейсом a.A и Синяя книга Если есть ситуация:

type A interface{ 
    Foo() b.B 
} 

, и вы должны написать реализацию для a.A, то вам необходимо импортировать пакет б. Но это делает ваши двоичные файлы не большими, потому что вам всегда нужно будет импортировать пакет a, который зависит от b.

+0

нет, совсем не теоретический. Это две проблемы, которые у меня есть. Мне «нужно», чтобы изменить хорошее предложение, но поскольку я не являюсь владельцем всего, от которого я зависим - «Я» не могу его изменить. Для второго вопроса пример io.Writer не имеет ничего общего с моим случаем. Почти каждый интерфейс, который не является явно тривиальным, поскольку io.Writer требует нескольких интерфейсов. Поскольку я не пишу стандартные библиотеки, где зависимости получены неявно - проблема очень реальна. – gsf

+0

Извините, если это звучит немного сложно. Это не должно быть намерение, английский не является моим первым языком. Но когда у вас есть существующий код, это поможет узнать немного больше о существующей структуре и о том, какие части вам нужно реализовать. И я знаю, что ваша проблема не в io.Writer, которая была всего лишь примером. После прочтения всех дополнительных комментариев я понимаю вашу проблему. Если ваш внешний пакет a использует внешний интерфейс b.B, нет другого способа решить это, а затем импортировать пакет b. – apxp

+0

У меня есть протокол, который включает в себя несколько интерфейсов - точно так же, как объяснено. A возвращает B. Оба они принадлежат к одной и той же упаковке. Теперь из-за этого мне невозможно создать реализацию этих интерфейсов без прямой зависимости от этого пакета. Это будет возможно, если я этого не сделаю - вот в чем проблема. – gsf

Смежные вопросы