LINUX.ORG.RU

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

 , , ,


0

4

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

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

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



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

на нем пишут от консольниых утилит и до высоконагруженных сетевых сервисов

Это и есть его основная ниша, он для этого и создавался. Если для чего-то другого его использовать, надо уже крепко подумать.

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

Ты же понимаешь, что даже в сишке разработчики извращаются с return -1 и всякой нечистью с глобальными флагами, лонгджампами и прочей мутотенью вместо того чтоб договориться о том, что результатом return всегда должен быть struct у которого есть поле bool isFine или как там они договорятся, дальше data, где собственно твоё значение и errorMessage куда можно внести текст с описанием ошибки. Так почти никто никогда не пишет. Надо ли объяснять почему это хуже, чем try catch с механизмом исключений? Хотя если сахаром присыпать и язык изначально с таким подходом делать, то может и можно что-то приличное слепить. Только надо у каждого типа делать метод isFine и getError. Или даже достаточно getError и возвращать текстом пустую строку, если всё хорошо и что-то непустое в противном случае.

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

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

Да всё просто. Поднимаешься, пока не найдёшь catch. Я просто не понимаю, зачем это всё? Я 20 лет пишу на Java и никуда не поднимаюсь никогда. Ошибка в любом случае будет где-то обработана. Про это просто не надо думать. Ты думаешь про business value. Про счастливый путь выполнения. И сам становишься счастливей. Потом уже задеплоишь, увидишь в логах, что какой-то конкретный кейс спамит стектрейсами и решишь, что вот именно тут можно сделать более конкретную обработку, возвращая не 500, а что-нибудь более конкретное, например. Но это одна ошибка из миллиона возможных, а оставшийся миллион всё так же обрабатывается автоматически и без приложенных усилий.

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

Исключения превосходно подходят для обработки всех ошибок, что и доказала Java. Checked исключения упоминать смысла нет, это была ошибка дизайна языка и в современной Java они уже давно не используются.

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

Не надо просто ничего ловить. Словит тот, кому положено. Если запись в логи кидает исключение, значит надо прерывать выполнение. Я больше скажу, если запись в логи кидает исключение, надо просто завершать выполнение всей программы, это не просто исключительная ситуация, это прям критическая ситуация.

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

Да нет никакого throws, я уже написал, что checked исключения никем не используются. IOException надо просто сразу же оборачивать в UncheckedIOException из стандартной же библиотеки и дальше забывать про него.

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

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

Для меня любой стектрейс это работа на 2 минуты. Ты просто щёлкаешь по именам файлов, строкам в IDE и перед тобой кристально ясная картина произошедшего. Если говорить про идеальный мир, я бы вообще хотел, чтобы в стектрейс дампились значения всех локальные переменных и параметров, если бы я делал свой ЯП, я бы так и сделал. Но в принципе и так сойдёт. А когда есть кристально ясная картина произошедшего, то работа над ошибкой проста и быстра.

А в Go мы видим bla: foo: bar в логе. И почесав в затылке начинаем писать grep -R 'bla' ., видим 20 вхождений, потом грепаем по foo и начинаем строить граф вызовов между всем этим безобразием, пытаясь предположить, хотя бы где именно эта ошибка возникла, на какой строке, про причину тут пока даже разговора не идёт. Это как махать каменным топором после бензопилы.

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

Всё преимущество Go в шикарной реализации. Удобный набор инструментов для разработки. Шикарный компилятор, наверное самый быстрый в индустрии. Скомпилированный код работает шустро. GC очень хороший. Зелёные потоки, идея на мой взгляд спорная, но тут у меня твёрдого мнения нет, и в Go они сделаны на отлично. В общем как язык - так себе. А как реализация - да, всё прям супер. И это в общем-то побеждает в итоге. Java как язык может и лучше, но там VM будет стартовать полсекунды, а в Go программа за это время успеет отработать десять раз, и пользователю просто будет приятней пользоваться такой программой.

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

Для меня выглядит довольно дико писать код, не думая об ошибках. Даже если тебе на 99% пофиг, 1% может быть важным, закрывать на него глаза до последнего момента ненадёжно. Таймауты, доступ к ресурсам, неверный ввод — это рутина, а не чья-то чужая забота. И когда я попадаю в незнакомый код, то локальность проброса позволяет легче понять что происходит. Я никогда не чувствовал потребности видеть только счастливый сценарий чужого кода.

закат солнца вручную

errors.Wrapf — не закат солнца вручную. Но я могу понять, если тебе приходится работать с проектом, где этого нет или вместо точной строки написано “failure: failure: failure.” Я за 8 лет опыта на Go с таким сталкивался редко.

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

Для меня выглядит довольно дико писать код, не думая об ошибках.

А для меня важно только то, чтобы ошибка аккуратно уронила нужный контекст (например текущий запрос), оставив систему в консистентном состоянии, просигнализировав кому положено о ситуации максимально подробно (например записав стек в логи и отдав HTTP 500). Это всё, о чём я думаю. И этого практически всегда хватает. Конечно бывают ситуации, когда действительно важно показать пользователю правильное сообщение об ошибке, когда важно обработать ошибку нетривиальным образом и тд и тп, но такие ситуации редки. А в коде безумное множество того, что может выдать ошибку в теории, но на практике не выдаст. И чуть меньше, но тоже много того, что ошибку изредка может выдать, но универсальной обработки для этой ошибки хватит за глаза. И пытаться обрабатывать все ошибки - верный способ написать уйму кода, который никто никогда не протестирует и который как раз совсем не факт, что в реальности сработает адекватно.

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

Я соглашусь лишь с тем, что значения локальных переменных, которые программист засунет в сообщение об ошибке, могут быть весьма полезными и в Java стектрейсах их может не хватать (хотя никто не мешает в Java писать ровно такой же код в уместных местах - ловить исключение и перевыбрасывать с дополнительной информацией).

errors.Wrapf

Что такое errors? Это This repository was archived?

Насколько я знаю, стандартный способ в Go нынче это fmt.Errorf в который вообще-то могли бы добавить информацию о стектрейсе, пускай даже включаемую через какой-нибудь ENV или ещё как-нибудь.

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

fmt.Errorf в который вообще-то могли бы добавить информацию о стектрейсе

Вот такой велик давеча нашел. Сам не пробовал еще.

Но там

To achieve the performance above on supported systems, errtrace makes use of unsafe operations

ко-ко-ко итокдалие )))

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

Сделать свой класс ошибки с фреймом стектрейса я, наверное, и сам смогу, не рокет саенс, тут дело не в этом, а в том, что хочется писать идиоматичный код, а идиоматичный код это fmt.Errorf.

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

облепливая её дополнительной информацией и в конце концов обрабатывая её каким-то универсальным кодом. Это нормально. Ненормально только то, что синтаксис языка активно сопротивляется этой практике.

errors.Join, errors.Is, errors.As. Да, арсенал работы с ошибками у нас специфичный, это многие отмечают. Но он есть и при правильном приготовлении дает все желаемое.

В целом, нравятся твои рассуждения о языке, спасибо :)

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

Сделать свой класс ошибки с фреймом стектрейса я, наверное, и сам смогу, не рокет саенс

Конечно, в std/runtime все есть, забирай.

История со стектрейсом пишется за полдня (если приемлемо, либо за день если нужно поумнее) и так-то есть в любом логгере, если нужна. Вот только вопрос, действительно, нахрена стектрейс, если ошибка - это значение. Да, тут есть нюансы, но если принять правила игры, то стектрейс не особо нужен. В нем не будет данных, которые сломали обработку, а вот в ЗНАЧЕНИЕ ошибки их можно положить, ага. Короч, работа с ошибками очень специфическая.

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

Сделать свой класс ошибки

Лучше что-то типа приемов стандартной библиотеки. Например https://pkg.go.dev/io/fs#PathError

И дальше вот этот errors.As.

Я видел ну много разных вариаций на тему переизобретения обработки ошибок в Go, все они были унылым говном, называя вещи своими именами. Стандартная библиотека задает неплохой ориентир, т.к. ее придумывали не всякие там школьники, а умные люди. Еще надо понимать, что чем дальше от механизмов стандартной библиотеки мы отойдем (в сторону изобретения велосипеда, в большинстве случаев), тем тяжелее будет поддерживать код. Я язык, в сущности, про коммерческую быструю разработку… Короч, есть нюансы :)

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

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

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

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

Для меня любой стектрейс это работа на 2 минуты. Ты просто щёлкаешь по именам файлов, строкам в IDE и перед тобой кристально ясная картина произошедшего. Если говорить про идеальный мир, я бы вообще хотел, чтобы в стектрейс дампились значения всех локальные переменных и параметров, если бы я делал свой ЯП, я бы так и сделал. Но в принципе и так сойдёт. А когда есть кристально ясная картина произошедшего, то работа над ошибкой проста и быстра.

И все было бы прекрасно, если бы единственным пользователем твоего приложения был ты сам. Но в реальном мире это обычно не так. Простой пример: есть у тебя сервис с кучей зависимостей, и не смог он сходить в условный редис и упал. Человекочитаемая ошибка: не могу подключиться к сервису X по адресу Y: ошибка из метода подключения (например, не те креды, или i/o timeout). И вот человек, запускающий твой сервис, и не имеющий доступа к коду, сразу все понял и поправил. Можно ли то же самое выдернуть из портянки стектрейса? Конечно, но из 100 строк полезна там ровно одна, а срет он им непрерывно.

George
()
Ответ на: комментарий от Zhbert

Ну не совсем. В жабе есть нормальное implements, с контрактом и прочим. В го есть только сраный цирк с конями, где понять кто кого имплементит не особо возможно без толстой ide-шной обвязки

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

Но всё-таки рецепт пирога на Го выглядит приблизительно так:

1) Открой холодильник. Если не получилось, скажи, что не получилось.

2) Найди яйца. Если не получилось, скажи, что не получилось.

3) Достань три яйца. Если не получилось, скажи, что не получилось.

4) Разбей яйца в миску. Если не получилось, скажи, что не получилось.

5) Подумай о вечном. Если не получилось, скажи, что не получилось.

...

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

В С++ есть исключения и они реально используются стандартной библиотекой, например new бросает bad_alloc, поэтому тебе не надо проверять его результат.

Поэтому нет, в С++ программа не должна выглядеть именно так.

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

Расскажи это эмбеддеду и прочим направлениям, где флаг -fno-exceptions - обязательный, а бывает, что и -fno-rtti - тоже.

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

Расскажи это эмбеддеду и прочим направлениям, где флаг -fno-exceptions - обязательный, а бывает, что и -fno-rtti - тоже.

Предлагаешь добавить в Go флаг

--dont-panic

для автостопщиковэмбеддщиков?

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

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

Это может иметь смысл только там, где флеша прям впритык. Но такое кажется в современном мире встречается всё реже.

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

ошибка аккуратно уронила нужный контекст (например текущий запрос)

Для меня «аккуратно уронить» обозначает сделать так, чтобы вызывающему было хорошо. Вызываемая функция может сообщить что пошло не так (“parsing $url as HTML: $err”), сделать удобное определение ошибки (по значению, типу, поведению). Ничто не мешает это повторить в исключениях, но в исключениях мы не ожидаем мгновенной реакции на ошибку, это чья-то чужая проблема, поэтому нет стимула напрягаться.

То, что ошибка должна обработаться где-то выше — это естественно. Ненормально заранее не думать об этом.

оставив систему в консистентном состоянии

ACID? Было бы, наверное, хорошо, если весь мир был ACID, но в реальности зоопарк. И здесь обработка ошибок может оказать огромную услугу: освобождение неиспользованного хранилища, очистка грязных глобальных данных, отмена начатых незаконченных операций, обработка неполных данных, сохранение сложных вычислений или ввода пользователя.

И этого практически всегда хватает.

«Хватает» в том смысле, что в штате тысяча программистов, готовых разгребать падающие системы хоть каждый день, лишь бы деньги платили?

Хотелось бы долгосрочных улучшений.

Конечно бывают ситуации, когда действительно важно показать пользователю правильное сообщение об ошибке

В идеале всегда. Стек-трейс – это инструмент даже не для программиста, а для разработчика. А пользователем может быть кто угодно, в том числе разработчик. Обработка ошибок позволяет это обеспечить, следуя общему правилу «если f(x) упала, укажи f и x в ошибке».

когда важно обработать ошибку нетривиальным образом и тд и тп, но такие ситуации редки

Они станут ещё реже, если о них вообще не думать. Когда, в сотый раз дополняя ошибку, будешь писать “server failed to respond”, в голову может прийти идея сделать повторный запрос. Или продолжить выполнение с изменённым конфигом. Или проигнорировать и быть уверенным в том, что игнорирование точно уместно (скажем, удаление временных ресурсов), а не кто-то до тебя зачем-то оставил пустой catch-блок.

А в коде безумное множество того, что может выдать ошибку в теории, но на практике не выдаст.

Ещё как выдаст, просто этот момент ещё не наступил. Как раз когда падает самая надёжная операция, больше всего хочется узнать причину.

универсальной обработки для этой [редкой] ошибки хватит за глаза

Стек-трейсы содержат иерархию вызовов и точку отказа. Ни то ни другое не указывает однозначно на природу ошибки и не содержит дополнительного контекста. Можно получить из канала io.Reader, в котором внезапно окажется сетевой ресурс, и ошибку придётся дебажить.

И пытаться обрабатывать все ошибки - верный способ написать уйму кода, который никто никогда не протестирует и который как раз совсем не факт, что в реальности сработает адекватно.

Примерно то же самое можно сказать про защиту от дурака (она же defensive programming). Тем не менее, польза ни у кого не вызывает сомнений.

Что такое errors? Это This repository was archived?

Да. Не знаю что лучше выбрать в 2026. Но вообще никто не запрещает хоть самому велосипед написать. То, что в стандартной библиотеке есть fmt.Errorf и errors — это аргумент, но не причина отказываться от сторонних решений, как никто не отказывается от сторонних HTTP-роутеров.

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

Для меня «аккуратно уронить» обозначает сделать так, чтобы вызывающему было хорошо.

Для меня «аккуратно уронить» означает, что система не останется в плохом состоянии. К примеру память не утечёт (тут, слава богу, GC справляется, но в том же C++ это целая эпопея). В целом это не сложно, если придерживаться определённых правил, например работать с СУБД с помощью транзакционных операций, чтобы ошибка откатывала все операции, а не оставляла половину в БД.

Что значит «вызывающему было хорошо» я не вполне понимаю. Если произошла ошибка, ему априори хорошо не будет. И тут максимум полезного, что можно сделать - это сообщить ему тип ошибки, по которому он сможет понять - стоит ли пытаться повторять действие.

Вызываемая функция может сообщить что пошло не так (“parsing $url as HTML: $err”), сделать удобное определение ошибки (по значению, типу, поведению).

Это всё никому не нужно и будет утеряно в дебрях developer console какой-нибудь. Тут хорошо подходит концепция трейсов. Когда у нас с выполнением кода и логами связан некоторый идентификатор, который мы и вернём клиенту. И если клиенту захочется разобраться - а что же случилось - он скажет нам идентификатор и мы в своих логах поищем, что нам известно про этот запрос. В идеале это вообще работает сквозным образом через сервисы.

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

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

Что значит «вызывающему было хорошо» я не вполне понимаю.

Указать в сообщении что произошло, чтобы вызывающему не пришлось быть чрезмерно многословным в пробрасывании ошибки. Например, os.Open/Read/Write/Close добавляют имя файла. Иногда вернуть частичную информацию (например, при чтении данных). Указать тип (или поведение через интерфейс), чтобы вызывающему было удобно среагировать. Если уместно, аггрегировать ошибки. Смысл в том, чтобы учитывать это заранее, в момент написания кода.

работать с СУБД с помощью транзакционных операций

Если повезёт, они будут. В некоторых их специально нет. При межсервисном общении тразакций нет по-умолчанию.

Тут хорошо подходит концепция трейсов.

Трейсы относительно обработки ошибок - как PostgreSQL относительно файлов. То есть не везде можно применить (не будешь же трейсы ставить на каждый вызов), несоразмерно сложнее в использовании и обслуживании.

Строка ошибки - идеальный баланс между ясностью (которую Go поощряет на всех уровнях) и простотой.

И если клиенту захочется разобраться - а что же случилось - он скажет нам идентификатор

  1. Ошибка может произойти на инфре клиента, доступ вряд ли дадут
  2. Идентификатор может протухнуть

Выплюнули строку из 20 символов и потом думай - что это такое.

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

Server failed: initialize server: load config from /etc/myapp/config.json: open /etc/myapp/config.json: no such file or directory

Server failed: handle request for user 123: query user 123: sql: connection is already closed
kaldeon ★★
()
Последнее исправление: kaldeon (всего исправлений: 5)
Ответ на: комментарий от kaldeon

Ну вот второе сообщение, прям наглядный пример. И что мне с ним делать? Где в коде искать о каком SQL вообще речь идёт? grep -R 'query user' да? (: Как я пойму, почему соединение уже закрыто? Анализируя все возможные пути, по которым программа могло дойти до нагрепанной строчки? А если там накопипастили 20 методов с одинаковым сообщением об ошибке?

А со стектрейсом сразу будет видно - на какой строке вызов и как до этого вызова мы дошли.

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

Во-первых, сразу видно что пытались делать и что помешало. Похоже на то, что не получилось аутентифицировать пользователя. В стек-трейсе эта информация присутствует в неявном виде и только для тех, кто знает структуру проекта.

Пару раз поиск выполнить должно помочь (grep -R ‘query user’, затем grep -R ‘handle request for user’). В крупных проектах добавляют название функции в строку ошибки.

Мне кажется, тут ещё SQL-драйвер мог бы оказать услугу, написав адрес подключения.

Как я пойму, почему соединение уже закрыто?

Это уже ни стек-трейсы, ни ошибки не подскажут.

А если там накопипастили 20 методов с одинаковым сообщением об ошибке?

Копипастить вредно и не только по этой причине.

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

А со стектрейсом сразу будет видно - на какой строке вызов и как до этого вызова мы дошли.

Если только не обмазываться фреймворками и инверсиями контроля, а то тогда стэктрейс превращается в кашу с кучей ненужного мусора из внутренностей фреймворка. https://ibb.co/vvwqZhhn

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

Пару раз поиск выполнить должно помочь (grep -R ‘query user’, затем grep -R ‘handle request for user’). В крупных проектах добавляют название функции в строку ошибки.

А может быть в крупных проектах используют структурированное логирование и агрегаторы логов, а не «ехал грепа через грепу». А также, возможно, трассировку запросов.

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

Я не вижу как одно мешает другому. Звучит как «postgresql вместо переменных».

ехал грепа через грепу

В чём, собственно, проблема?

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

Здравствуйте.

Интерфейсы это переходники которые соединяют компоненты системы. Конкретно в Go они описывают набор методов которым должна соответствовать структура.

В Go есть правило хорошего тона: функция принимает как аргументы интерфейсы, а возвращает объект конкретного типа. Интерфейсы широко используются в стандартной библиотеке Golgan. Таким образом библиотечные функции могут принимать через «переходник» объекты разных типов. Объектами я называю структуры - так привычней.

Например обработка HTTP запроса в пакете net/http происходит через экземпляр интерфейса Handler. Т.е. любого объекта который соответствует требованиям интерфейса Handler. И этот объект вы отдаете «марушрутизатору» который запускает его и этот экземпляр формирует ответ.

Сам объект формирует ответ через вызов метода SeveHTTP - который опять принимает два аргумента описанных интерфейсами Response и Request. В Response - пишется ответ через интерфейс Writer.

Видите, все взаимодействие в Go описывается не конкретными типами, а интерфейсами, т.е. можно передавать разные объекты, главное чтоб они выполняли требование интерфейса.

Интерфейсы - это концепция не для новичков. Надо набить опыт процедурного программирования иначе это достаточно бесполезно объяснять, все равно что рассказывать про комплексные числа ученику 3го класса школы.

У меня есть обобщающая статья «Интерфейсы в ООП».

Это вывод из прочтения двух книг:

  1. POODR от Sandi Metz. Необхоима для понятия концепта.
  2. «Learning Go» от Jon Bodner. Необходима для понятия реалзиации.

Рекомендую сначала прочитать книги. Иначе не будет базиса для восприятия этого концепта.

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

Раз уж это тема об интерфейсах. До сих пор юзаешь Acme?

Давно не юзаю )

Что понравилось

Простота, довольно удобно работать мышкой, типа двигать колонки и окна, выполнить любой текст как шелл-команду, вообще мышь становится более функциональной как будто.

в чём разочаровался?

Прям разочаровался хз, вроде не в чём, я что ожидал (по демо-видосам), то и получил.

Ну, пожалуй, очень непривычно, что клавишы-стрелки вниз/вверх не перемещают каретку ввода на строку выше/ниже. Наверное, со временем можно привыкнуть.

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

И я так понимаю, в окнах Acme можно только текстовые приложения запускать, то есть, например, нельзя интегрировать в него веб-браузер для просмотра документации, или просмотрщик картинок/pdf-файлов. А раз так, то проще какой-нибудь тайлинговый WM юзать, может с меньшей интеграцией между приложениями, но зато с более широким спектром одновременно видимых приложений, связанных логически.

korvin_ ★★★★★
()