LINUX.ORG.RU

интерфейсы в GO

 , , ,


0

3

Читаю и не как понять не могу что такое интерфейсы в GO ??

можно пояснить

Есть только понимание что они работаю с некоторым количеством методов.



Последнее исправление: antonio-an (всего исправлений: 1)
Ответ на: комментарий от amm

Абсурд. Альтернатив Гошке нет вообще.

Любой другой ЯП либо недоразвитое говно, либо перегружен говном.

Всё старые ЯП в принципе обсуждать нет смысла — устаревшее говно не успевающее за реальностью.

А что остаётся? Да в принципе ничего. Раст — это про другое. Котлин — тоже. Что там ещё? Да больше ничего и нету.

thegoldone ★★★
()
Ответ на: комментарий от anonymous

в Го всегда были захардкоженные map[type1]type2. И всех все устраивало.

И вообще, чем больше ты думаешь над архитектурой программы и решаемыми проблемами, тем меньше тебе нужны коллекции.

Lrrr ★★★★★
()

Go - крайне простой язык программирования и там всё сделано крайнее просто. Интерфейсы в Go - это попытка реализовать то, что во всяких любимых народом шлакокнижках за авторством Р. Мартина и других называется интерфейсом.

dmaj
()
Ответ на: комментарий от vbr

Исключения запутывают поток выполнения, в отличие от. И поэтому чаще всего на них забивают, повсюду ставя throws или один catch (Exception) на весь блок. Для закрытия ресурсов вообще отдельная конструкция (try with resources).

kaldeon ★★
()
Ответ на: комментарий от amm

Они не ломают Go. Их было сложно реализовать таким образом, чтобы они не ломал Go. Но теперь они есть в языке и всё норм.

О том, что именно вызвало трудности:

  • Minimize new concepts
  • Complexity falls on the writer of generic code, not the user
  • Writer and user can work independently
  • Short build times, fast execution times
  • Preserve clarity and simplicity of Go

https://go.dev/blog/why-generics

Конкретные примеры можно найти в куче отклонённых предложений. Я лично не особо с ними знаком, но могу привести такой пример, возможно, слегка не по теме — сейчас нельзя добавить дженерик замыканию, потому что нужно сохранить нулевые значения, а без указания конкретного типа это невозможно. Подобные ограничения, мне кажется, делают невозможным подход «давайте всё спишем у C++/Java/C#».

kaldeon ★★
()
Последнее исправление: kaldeon (всего исправлений: 1)
Ответ на: комментарий от amm

Срез это не копирование и не владение. Это просто ссылка на область памяти (массива). Логично и понятно. Почти как обычные указатели в С. Не знаю, может ты с С не был знаком, перед изучением Go, потому и «не зашло».

Во всех языках (C, Java, Python) этот приём используется вручную, но в Go его встроили прям в язык.
Вот как выглядит аналогичный код на разных языках.

sort(arr, 0, len / 2); // C
arraycopy(src, 0, src.length / 2, ...); // Java
print_half(lst, 0, len(lst) / 2); Python
println(s[0:len(s) / 2]); // Go

В Питоне есть похожая нотация, но она делает копию а не ссылку.

urxvt ★★★★★
()
Последнее исправление: urxvt (всего исправлений: 3)
Ответ на: комментарий от kaldeon

Исключения запутывают поток выполнения, в отличие от

Наоборот. Постоянные return запутывают поток выполнения. А исключения позволяют не отвлекаться не несущественный код.

И поэтому чаще всего на них забивают, повсюду ставя throws или один catch (Exception) на весь блок

Один catch это гораздо лучше, чем миллиард if-ов, спасибо за аргумент в мою пользу.

Для закрытия ресурсов вообще отдельная конструкция (try with resources).

Или defer, ага.

vbr ★★★★★
()
Последнее исправление: vbr (всего исправлений: 1)
Ответ на: комментарий от vbr

Ну вот видишь ты throw new Exception, где он обработается? С return сразу будет видно.

Это несущественный код только для тех, кто привык писать ненадёжную скриптуху, ломающуюся от каждого пинка.

Один catch это гораздо лучше, чем миллиард if-ов, спасибо за аргумент в мою пользу.

Ну представь, что этот блок ловит исключения из 15 вызовов. По тексту кода вообще не видно что может пойти не так.

Захочешь добавить новый код и не поймёшь, правильно ли сейчас обработается твоё исключение одним общим блоком.

В общем, лень ≠ простота.

Или defer, ага.

defer — конструкция общего назначения, не обязательно для закрытия ресурсов. А try with resources — магия, которую добавили после провального try-finally.

kaldeon ★★
()
Последнее исправление: kaldeon (всего исправлений: 3)
Ответ на: комментарий от kaldeon

Ну вот видишь ты throw new Exception, где он обработается?

Где положено.

С return сразу будет видно.

Нет, не видно.

Ну представь, что этот блок ловит исключения из 15 вызовов. По тексту кода вообще не видно что может пойти не так.

Это не важно. Важно, что идёт так.

Захочешь добавить новый код и не поймёшь, правильно ли сейчас обработается твоё исключение одним общим блоком.

Чего это не поймёшь?

defer — конструкция общего назначения, не обязательно для закрытия ресурсов.

Да, как и try-finally.

А try with resources — магия, которую добавили после провального try-finally.

try with resources это синтаксический сахар для успешного try-finally. Который бы не помешал в Go, кстати говоря.

vbr ★★★★★
()
Последнее исправление: vbr (всего исправлений: 1)
Ответ на: комментарий от vbr

Где положено.

Разумеется, не на Луне. Только найти это место не очень удобно. По иерархии вызовов и типов придётся попрыгать и не ошибиться.

Нет, не видно.

Как это не видно? Обработка происходит в 99% случаев первым if-ом.

Это не важно. Важно, что идёт так.

То есть работа с ошибками не важна. Ну тогда мой аргумент про «ненадёжную скриптуху» в силе. Только непонятно что ей делать в энтерпрайзной Джаве или Шарпе.

Чего это не поймёшь?

Представь, что обработка ошибки отправляет какое-то межсервисное событие. Оно нужно для нового кода? Хз.

try-finally

Который превращает код в лапшу, если, например, закрытие неоткрытых ресурсов запрещено. Поэтому и был придуман try with resources.

[try with resources] … не помешал в Go, кстати говоря.

Зачем? Я ни разу не видел, чтобы defer плохо справлялся с очисткой ресурсов. Есть пример?

kaldeon ★★
()
Последнее исправление: kaldeon (всего исправлений: 2)
Ответ на: комментарий от kaldeon

Разумеется, не на Луне. Только найти это место не очень удобно. По иерархии вызовов и типов придётся попрыгать и не ошибиться.

И на Go придётся. Потому, что в 99% случаев там будет if err := bla(); err != nil { return err; } и это в хорошей программе, а в плохой вообще ничего не будет, лол.

Как это не видно? Обработка происходит в 99% случаев первым if-ом.

Нет, обработка происходит в 99% случаев где-то сверху по стеку.

То есть работа с ошибками не важна.

Конечно же работа с ошибками важна. Но не как в Go. А централизованно. Что позволяет гарантировать корректную работу с ошибками. А не как в го - проверил - хорошо. Не проверил - всем пофиг.

Поэтому

Ну тогда мой аргумент про «ненадёжную скриптуху» в силе. Только непонятно что ей делать в энтерпрайзной Джаве или Шарпе.

Ненадёжная скриптуха это как раз Go. Ибо там, чтобы обработать ошибку хоть как-то, нужно прилагать усилия. Примерно как в баше, лол. А в Java нужно прилагать усилия, чтобы НЕ обработать ошибку. Что автоматом повышает надёжность программы на порядок.

Про то, что информативность стектрейса на порядок выше какой-то рандомной строчки в Go - я даже не говорю.

vbr ★★★★★
()
Последнее исправление: vbr (всего исправлений: 3)
Ответ на: комментарий от vbr

Исключения для исключительных ситуаций. Они в принципе не должны использоваться. Использовать исключения для обработки ошибок – всё равно, что сжигать свой дом, для выведения тараканов.

Обработка ошибок в Гошке лучше всего. Не говно-errno, не исключения, не игнорирование.

thegoldone ★★★
()
Ответ на: комментарий от vbr

И на Go придётся. Потому, что в 99% случаев там будет if err := bla(); err != nil { return err; } и это в хорошей программе, а в плохой вообще ничего не будет, лол.

Есть ветвление. И оно есть явно. В чём пробелма? Ошибка никогда не возникает сама по себе. И у неё есть контекст. Вместо говнища вида failed something и километровой дрисни из стека, как в Яве. Ошибка возникает и ей даётся контекст. Поэтому в реальности это выглядит так

if err != nil {
     return fmt.Errorf("crap at %q with %d: %v", a, b, err)
}

В принципе – единственный способ уйти от ошибок вида 0x8394832 Broken unknown crap 2. И километровой дирсни из раскрученного стека.

А раскрутка стека на каждый чих – это вообще нечто.

thegoldone ★★★
()
Ответ на: комментарий от vbr

Конечно же работа с ошибками важна. Но не как в Go. А централизованно. Что позволяет гарантировать корректную работу с ошибками. А не как в го - проверил - хорошо. Не проверил - всем пофиг.

В случае ошибок го паникует. Го не будет терпеть попытку записи в закрытый файл, деление на ноль или разыменование нулевого указателя. С другой стороны, го спокойненько возвращает дефолтное значение при чтении несуществующего значения из хеш-таблицы, то есть в философии го это вообще не ошибка и не исключение. И эта философия неплохо работает на практике.

FishHook
()
Ответ на: комментарий от vbr

Примерно как в баше, лол. А

Баш как раз сверхговно по части обработки ошибок, где они в принципе игнорируются всегда. И никогда не ясно, что и где отвалилось.

thegoldone ★★★
()
Ответ на: комментарий от amm

Хлам – это твоё мнение. Всегда думал, что go чисто утилитарный язык, а не язык фанатиков.

Утилитарное – это мнение говнохранителей, которым не нравится Го. Ввиду лишь только того, что из него выкинули всё говно.

Ну да, как Вам может показаться, что без говна он перестал быть тёплым и мягким. Но в этом и есть его фишка. Так что проходите мимо. Не задерживайтесь.

thegoldone ★★★
()
Ответ на: комментарий от urxvt

Настолько логично и понятно, что это основной вопрос на собесах. Ссылаться на Си, объясняя косяк в современном языке, ну такое. И в Си как раз такого не будет, там всё логичнее, так как крнтроля за памятью никто не обещал.

amm ★★
()
Ответ на: комментарий от amm

Настолько логично и понятно, что это основной вопрос на собесах.

Так на собесах все базовое спрашивают, на то они и собеседования. :)

Ссылаться на Си, объясняя косяк в современном языке, ну такое. И в Си как раз такого не будет, там всё логичнее, так как крнтроля за памятью никто не обещал.

Я тебе пытаюсь показать, что это не косяк а Go это развитие C а не каких-то там питонов. Go это C с GC. Авторы сами говорили, что Go это была замена для C++.

urxvt ★★★★★
()
Ответ на: комментарий от amm
int[] array = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 } ;
Span<int> slice = new Span<int>(array, 2, 3);


Глянул — то же самое. В чем фундаментальное отличие?

о что в го – это херак, херак и в продакшен.

На самом деле, Го, один из самых (если не самый) продуманный и целостный язык.

urxvt ★★★★★
()
Ответ на: комментарий от amm

Дай погадаю. Ты бывший пхпшник :) Отсюда и комплексы.

Ожидаемо мимо. Видеть очевидное теперь комплекс? Не знал. Это в кругах кого, если не секрет? Говнохранителей?

Мир не стоит на месте. Примите уже это. Всё что Вы знаете устаревает со скоростью минута в минуту. Если лично Вы перестали успевать, то в этом никто не виноват. Никто, кроме Вас.

thegoldone ★★★
()

По поводу срача языков.

  1. Go - делать достаточно быстрые бинарники так, чтобы с рынка легко хантились разработчики, которые смогут это поддерживать. Требование доступности разработчиков на рынке здесь прямо основное. Язык ограничен в сложности как раз для этого, а компиляется в бинарник для скорости. Заточен под написание бизнес-логих в бигтехах: яндексы, озоны, VK, гуглы. Когда надо налабать быстро некую новую систему и чтобы оно было машинным кодом, но при этом чтобы исходник выглядел не как жопа на C++. Управление памятью вынесли в GC, как раз чтобы эти жопошники изобретатели аллокаторов в C++ пошли лесом и не плодили костылей.

  2. C++ - делать максимально упорото производительные бинарники, где разраб должен думать про всё, максимальный контроль человека. Иногда это надо. Это типа как армейское оборудование и вооружение на рынке. Допускают только профессионалов, хантить их тяжелее, можно оторвать себе кусок жопы неудачным выстрелом и расхерачить пол-страны и потерять все полимеры. Относятся с опаской.

  3. Rust - когда не хочется GC, хочется приблизиться к C++, но при этом гарантировать на этапе компиляции отсутствие дедлоков, проездов по памяти чужого массива или запись по указателю, по которому не планировалось записывать или разлочивание того, что не планировалось разлочивать и т.п. В некоторых вещах C++ обогнать не получается, потому что некоторые проверки в Rust неизбежно делаются в рантайме за счёт CPU, а не компилятора (всякие там if-ы на границы массива). Писать на Rust сложно, потому что тебя постоянно бьют по башке палкой, буквально выясняется что как ты раньше писал - это в корне ошибочно на каждом шагу и нужно больше точности и определённости. Но у Rust есть злые враги - системы формальной верификации программ: для любой программы на голом Си можно описать некий «Образ» на специальном языке (их штуки 3 видел, забыл уже), а потом специальная машина доказывает, что софтина формально корректна и ей негде падать. Вроде бы таким макаром делают микроядра гипервизоров, которые внутри айфона сверху надзирают над iOS чтобы когда хакеры получили root всё равно не смогли доступ к драйверу модема получить.

  4. TypeScript - довольно неплохая штука: буквально статически типизируемый JS с дополнительными свистоперделками, выглядит достаточно неплохо, строго и не сложно. Транслируется в JS. JS умирать не собирается, глубоко укоренился в браузерах, выполняется тоже быстро, потому что компиляется в машинный код JIT-ом.

lesopilorama
()
Последнее исправление: lesopilorama (всего исправлений: 3)
Ответ на: комментарий от urxvt

То что нет неявного копирования при расширении, точнее спаны в шарпе вообще не расширяются, надо расширить – пожалуйста, копируй ручками.

amm ★★
()
Ответ на: комментарий от urxvt

На самом деле, Го, один из самых (если не самый) продуманный и целостный язык.

Пайк, конечно, один из самых крутых программистов современности, но в желании сделать просто, он завёл го куда-то не туда. На универсальный язык он явно не тянет.

amm ★★
()
Ответ на: комментарий от amm

Все таки, фокус был не на универсальности, а создать язык для современных сетевых сервисов. Заменить в этой нише C++ в Гугле.
Но, судя по тому, что на нем пишут от консольниых утилит и до высоконагруженных сетевых сервисов, и СУБД язык получился достаточно универсальным.

urxvt ★★★★★
()
Ответ на: комментарий от amm

Я, как и авторы языка, не против дженериков. Мнение, что их добавили злые манагеры — конспирология. Их добавили Иэн Лэнс Тейлор (ключевая фигура в команде) и Роберт Грисмер (один из авторов языка).

kaldeon ★★
()
Ответ на: комментарий от vbr

В Go, конечно, тоже придётся попрыгать. И return, и throw – похожие механизмы прерывания потока выполнения. Но в случае с Go тебе достаточно подняться на один уровень вверх и ты уже стоишь на строке, которая пробрасывает или обрабатывает ошибку. “return fmt.Errorf” — это тоже полезная информация, сразу сообщающая «не здесь». В Java недостаточно подняться на один уровень вверх, придётся ещё проверить список throws, окружающий try {} catch блок, который дополнительно зависит от иерархии типов. Нет локальности проброса как лексического понятия, то есть возможности понять поведение кода, глядя только на текущую функцию и её непосредственное окружение, а имеющаяся лексическая информация вроде throws неполна.

Исключения изначально были созданы для обработки исключительных ситуаций. Именно поэтому им позволено так легко ломать поток выполнения. Но не все ошибки должны быть исключительными. Нет ничего исключительного, достойного сказать «не моя проблема», если, например, файл вдруг не открылся. Java попыталась адаптировать исключения, сделав их более контролируемыми, но тем самым смешала два принципиально разных понятия в одну неразличимую кучу. (Unchecked исключения делают проблему ещё острее.)

А централизованно.

Например, ловим мы IOException. Его может выбросить бд, устанавливающая соединение через соккет, или запись в логи. При записи в логи не нужно прерывать работу метода. Это не редкость. И в чём преимущество централизации?

Что позволяет гарантировать корректную работу с ошибками. А не как в го - проверил - хорошо. Не проверил - всем пофиг.

Да, Java даёт определённые гарантии, но при этом поощряет перекладывание исключения в throws. Учитывая то, кто каллером может быть потенциально кто угодно, всегда есть надежда, что где-то в глубине есть могучий Атлант try-catch, который точно знает что делать с твоим исключением.

Но и в Go тоже есть гарантии. Ты не можешь просто написать data, err := hello(), не обработав err (компилятор запретит). Как раз нужно приложить усилие, чтобы НЕ обработать err — написать странную конструкцию data, _ := hello(). Так делают, но крайне редко, в проде почти никогда, потому что компилятор постоянно сталкивает программиста лбом с ошибками.

(Функции, возвращающие ошибку как один аргумент — меньшинство, но да, это недостаток. Однако, здесь мы переходим от темы про исключения к теме про result.)

Примерно как в баше, лол.

Очень большое преувеличение. В Go ошибки – это значения. Соответственно, улучшая работу со значениями (например, запретом на неиспользуемые переменные), мы улучшаем обработку ошибок. В баше ошибки – коды возврата, то есть протекающая абстракция ОС, которую мы можем получить магической переменной $?. Функции в шелле не возвращают ошибки как значения (строго говоря, функция в шелле вообще ничего не «возвращает» в смысле обычных языков).

информативность стектрейса на порядок выше какой-то рандомной строчки в Go

Никто не запрещает захватывать стек-трейс в Go. Никто, вроде, не считает это неправильным.

kaldeon ★★
()
Последнее исправление: kaldeon (всего исправлений: 3)
Ответ на: комментарий от amm

Не спорю с тем, что в Шарпе сделали хорошо. Но у подхода Го тоже есть своё достоинство — единая абстракция, покрывающая все нужды и предлагающая идеальный баланс между удобством, простотой модели и производительностью. Неявное копирование можно потерпеть, оно на практике нечасто приводит к проблемам.

kaldeon ★★
()
Последнее исправление: kaldeon (всего исправлений: 1)