Pull to refresh

Comments 18

«Увы и Ах», многие беженцы с других языков используют пустые интерфейсы по сути для отмены типизации. Это неидеоматично, уродливо, небезопасно и медленно.
Пару раз пытался увещевать: «мол, не делайте так, сделайте лучше нормальный интерфес». В ответ лишь непонимание…

А может пытаются таким образом компенсировать отсутствие дженериков?

Если бы []SomeType удовлетворяло []SomeInterface (при том что SomeType удовлетворяет SomeInterface), то в большинстве случаев не понадобилась бы ни такая компенсация, ни разработка дженериков в самом языке.

Ну это справедливо лишь для boxed типов.

Если бы []SomeType удовлетворяло []SomeInterface (при том что SomeType удовлетворяет SomeInterface),

Э нет, всё не так просто. Вы говорите о ковариантности и контравариантности. Нельзя просто так сделать, чтобы оно отвечало, ведь если пойти по одной тропинке — другая будет закрыта.

А может пытаются таким образом компенсировать отсутствие дженериков?

0. Может быть вы имели ввиду наследование? Это, бывает, что нужно, да.
1. Но чистые generic же нужны для очень небольших кусков алгоритмов (типа универсальная сортировка на все случаи жизни)
2. Это же можно компенсировать в ряде случаев определенными интерфейсами (кстати, посмотрите как это реализовано в сортировке в Go).
3. Но используют везде — даже в тех случаях, когда не нужно.

Просто силь людей, пришедших с языков с динамической типизацией, и не обращающих внимание, что в статической типизации многие вещи делаются иначе.
0. Так вроде наследование есть в Go.
1. Я считаю что дженерики хорошо подходят именно в библиотеках, к примеру в стандартной библиотеке Java или C++ их довольно много (особенно при реализации базовых интерфейсов Map, List и т.д) и позволяет обходится без interface{}-хаков. А в Go стандартная библиотека изобилует interface{}-конструкциями, далеко ходить не надо — fmt.PrintLn к примеру, или пакет text/template, где во внутренней реализации их тоже много. Я понимаю что это похоже на C-way, где для этого применяют void*, но не думаю что это хорошая практика в современном программировании.
2. Утиная типизация из интерфейсов хороша, но как показывает практика использования interface{} в библиотеках — не всегда применима.

Просто силь людей, пришедших с языков с динамической типизацией

Согласен, но дженерики всё таки появились в статических языках, когда статическая типизация достигла своего потолка возможностей. Вспомнить хотя бы Java в эпоху до версии 5.0, где повсюду был Object-ад с приведениями типов. Да, в прикладном коде дженерики почти не используются, если только не реализуешь свои абстрактные типы данных или алгоритмы, но в библиотеках это must have.
Так вроде наследование есть в Go.

В Go нет наследования, потому что в современном понимании — это не объектный язык. Есть только имплементация интерфейса (утиная типизация), и встраивание типов. Ни одно из них по своей сути наследованием не является.

Однако с дженериками не так просто. Они нужны постоянно, просто у нас есть два встроенных хака в виде массивов и map.

Это похоже на то, что в функциональных языках называют классы типов (type classes). Верно?
type classes намного более экспрессивны чем interface'ы
Можно много говорить, вот читайте сами: stackoverflow.com/questions/6948166/javas-interface-and-haskells-type-class-differences-and-similarities
Но вот маленький пример (из ответа на стэке):
it's really hard to make things like add :: t -> t -> t with an interface, where it is polymorphic on more than one parameter, because there's no way for the interface to specify that the argument type and return type of the method is the same type as the type of the object it is called on

то есть сделать interface который скажет, вот есть функция, должна работать на любом типе (который имлементирует интерфейс) берет два аргумента и возвращает такой же. На Гоу или Джава интерфейсах такое нельзя гарантировать.

А с этим случайно не помогут контракты из недавно предложенного варианта дженериков для го?

не знаю насколько контракты это смогут решить (к сожалению не осилил proposal, так как «многа букаф»)

Нет. Классы типов — это совсем другая концепция.


  1. Контракт (класс типов) — отдельно
  2. Тип — отдельно
  3. Реализация контракта (экземпляр класса типов) для типа — отдельно
Судя по коду в этой статье, все 3 пункта соблюдаются. Я же не говорю что это тоже самое, но ведь похоже?

Не соблюдаются и не похоже.
Никакой отдельной реализации контракта для типа нет.

Sign up to leave a comment.