Size: a a a

2020 June 07

S

Sergey in Go-go!
это в смысле не оборачивать функцию в функцию только ради вызова функции, а просто создать алиас и не страдать ерундой
источник

AK

Anton Kucherov in Go-go!
V L
Когда нужно - это ключевое. Обычно возвращают интерфейсы ради интерфейсов как привычки из других ЯП.
Интерфейсы в сущности своей в других ЯП имеют то же назначение что и в Go. Разница только в деталях реализации (В Go например они разрешаются неявно). Из-за этого вам не нужно возвращать их везде, потому что компилятор сам понимает, когда структура реализует интерфейс. Но если моя задача - скрыть детали реализации, я буду вынужден вернуть интерфейс.
источник

ЗА

Заур Ашурбеков... in Go-go!
Sergey
это в смысле не оборачивать функцию в функцию только ради вызова функции, а просто создать алиас и не страдать ерундой
значит вы не совсем поняли идею
источник

VL

V L in Go-go!
Anton Kucherov
Интерфейсы в сущности своей в других ЯП имеют то же назначение что и в Go. Разница только в деталях реализации (В Go например они разрешаются неявно). Из-за этого вам не нужно возвращать их везде, потому что компилятор сам понимает, когда структура реализует интерфейс. Но если моя задача - скрыть детали реализации, я буду вынужден вернуть интерфейс.
Не уверен, что для этого нужно возвращать интерфейс. Для этого достаточно корректно разграничить приватные и публичные методы.
источник

S

Sergey in Go-go!
Заур Ашурбеков
значит вы не совсем поняли идею
ну расскажи, чем вызов функции из другой функции без какого-либо изменения входных или выходных параметров, будет отличаться от алиаса, кроме увеличения длинны стэка?
источник

DP

Daniel Podolsky in Go-go!
Anton Kucherov
Интерфейсы в сущности своей в других ЯП имеют то же назначение что и в Go. Разница только в деталях реализации (В Go например они разрешаются неявно). Из-за этого вам не нужно возвращать их везде, потому что компилятор сам понимает, когда структура реализует интерфейс. Но если моя задача - скрыть детали реализации, я буду вынужден вернуть интерфейс.
на самом деле - у нас интерфейсы могут и должны использоваться как инструмент decoupling

но на пракктике есть проблемы :)
источник

DP

Daniel Podolsky in Go-go!
Sergey
ну расскажи, чем вызов функции из другой функции без какого-либо изменения входных или выходных параметров, будет отличаться от алиаса, кроме увеличения длинны стэка?
и даже стек, скорее всего, не пострадает, оптимизатор выпилит прослойку
источник

AK

Anton Kucherov in Go-go!
V L
Не уверен, что для этого нужно возвращать интерфейс. Для этого достаточно корректно разграничить приватные и публичные методы.
https://github.com/google/exposure-notifications-server/tree/master/internal/storage вот гляньте на этот пакет.
Посмотрите что возвращает каждая реализация Storage. Она возвращает интерфейс Blobstore.
И я не вижу здесь никакой проблемы.
источник

VL

V L in Go-go!
Никакой проблемы, если фабрика параметризуема и в зависимости от параметров возвращает разные объекты, удовлетворяющие единому интерфейсу.
Мы скорее про привычку возвращать интерфейс там, где можно обойтись структурой.
источник

VS

Vyacheslav Sitnikov in Go-go!
Ivan
data := JsonUtcTime(col.(time.Time))
Спасибо!
источник

AK

Anton Kucherov in Go-go!
V L
Никакой проблемы, если фабрика параметризуема и в зависимости от параметров возвращает разные объекты, удовлетворяющие единому интерфейсу.
Мы скорее про привычку возвращать интерфейс там, где можно обойтись структурой.
С этим я согласен, но почему то на это акцент никто не ставит. Как итог очень часто правило "Возаращай структуры" возводят в абсолют и руководствуясь им начинают священную войну. Я поэтому и сказал выше, что это всего лишь рекомендация. не нужно воспринимать ее буквально.
источник

S

Sergey in Go-go!
В том, чтобы возвращать интерфейс, проблемы как таковой нет. В некоторых случаях иначе никак бывает. Просто надо понимать, что возвращая интерфейс вместо реализации, мы просто лишаемся гибкости в некоторой степени. И никогда заранее не угадаешь, где и когда эта гибкость может понадобится. Поэтому и существует эта _рекомендация_ - по возможности всегда возвращать реализацию. В общем случае минусов нет, зато плюсы есть.
источник

AK

Anton Kucherov in Go-go!
Sergey
В том, чтобы возвращать интерфейс, проблемы как таковой нет. В некоторых случаях иначе никак бывает. Просто надо понимать, что возвращая интерфейс вместо реализации, мы просто лишаемся гибкости в некоторой степени. И никогда заранее не угадаешь, где и когда эта гибкость может понадобится. Поэтому и существует эта _рекомендация_ - по возможности всегда возвращать реализацию. В общем случае минусов нет, зато плюсы есть.
Вот тут я совсем не понимаю, объясните, какой гибкости? Возвращая интерфейс, на мой взгляд мы наоборот получаем гибкость, т.к. можем подменить его любой реализацией (не нарушая контракта). Все чего мы лишаемся, это грязных хаков и говнокода, когда мы возвращая везде структуру, в какой то момент захотим таки нарушить контракт и дернуть оттуда деталь реализации которую не должны дергать напрямую. Потом мы дернем в другом месте другое поле структуры, а потом третье, и так далее, пока код не превратится в лапшу.
источник

ЗА

Заур Ашурбеков... in Go-go!
Sergey
ну расскажи, чем вызов функции из другой функции без какого-либо изменения входных или выходных параметров, будет отличаться от алиаса, кроме увеличения длинны стэка?
ну во-первых, вызов конструктора не сильно-то создаёт проблемы с временем выполнения программы
2) если мы говорим о пакете, как о реализации конкретного сервиса, то с чего бы использующим этот код нужно заглядывать внутрь и искать какие интерфейсы он реализовывает
3) для чекалки полноты реализации интерфейса обычно юзают хаки типо var _ = NewIncrementer(newIncrement), а тут всё и без этого работает
источник

VL

V L in Go-go!
Anton Kucherov
Вот тут я совсем не понимаю, объясните, какой гибкости? Возвращая интерфейс, на мой взгляд мы наоборот получаем гибкость, т.к. можем подменить его любой реализацией (не нарушая контракта). Все чего мы лишаемся, это грязных хаков и говнокода, когда мы возвращая везде структуру, в какой то момент захотим таки нарушить контракт и дернуть оттуда деталь реализации которую не должны дергать напрямую. Потом мы дернем в другом месте другое поле структуры, а потом третье, и так далее, пока код не превратится в лапшу.
Если в месте использования объявляется свой интерфейс, то да, не теряем. Однако обычно завязываются на интерфейс, предоставляемый вами, пишут под него моки для тестов и прочее, что увеличивает связанность.
источник

s

snip in Go-go!
Anton Kucherov
Вот тут я совсем не понимаю, объясните, какой гибкости? Возвращая интерфейс, на мой взгляд мы наоборот получаем гибкость, т.к. можем подменить его любой реализацией (не нарушая контракта). Все чего мы лишаемся, это грязных хаков и говнокода, когда мы возвращая везде структуру, в какой то момент захотим таки нарушить контракт и дернуть оттуда деталь реализации которую не должны дергать напрямую. Потом мы дернем в другом месте другое поле структуры, а потом третье, и так далее, пока код не превратится в лапшу.
интерфейс определяется в месте использования, если ваша функция возвращает интерфейс вместо реализации, то эта функция не сможет быть использована в другом пакете например где определяется свой интерфейс по месту использования.
источник

S

Sergey in Go-go!
А ещё если твоя структура реализует несколько интерфейсов - другие интерфейсы теряешь просто.
источник

AK

Anton Kucherov in Go-go!
В месте использования еще не означает "обязательно в кодовой базе клиента (использующего интерфейс)". Пример тому любая реализация IoC, например интерфейс http.Handler.
источник

s

snip in Go-go!
Anton Kucherov
В месте использования еще не означает "обязательно в кодовой базе клиента (использующего интерфейс)". Пример тому любая реализация IoC, например интерфейс http.Handler.
в месте использования означает там где непосредственно используется
источник

AK

Anton Kucherov in Go-go!
snip
в месте использования означает там где непосредственно используется
Кем?
источник