All streams
Search
Write a publication
Pull to refresh
191
0
divan0 @divan0

Пользователь

Send message
Вот это хорошо звучит, хотя «В Go нет ошибок» совсем вызывающе звучит — как никак но интерфейс error — это часть языка. И возьмите не «любую переменную», а «нужную переменную, которая содержит всю необходимую вам информацию об ошибке в нужной вам форме». Но так да, суть верна.
Хороший поинт. Кратко — потому что есть иные взгляды на обработку ошибок в других языках, которые, по мнению авторов Go (и не только их) принесли лишь дополнительную сложность и путаницу, и именно от этих взглядов так сложно избавится.

Как я понимаю, концепция «ошибки как значения» — естественная, её не нужно изобретать, это то, как мозг интерпретирует задачу. Но тут огромную роль играют конкретные аспекты конкретных языков. В C, например, возвращали код ошибки и дальше работали с ним — это было неудобно, многословно, это была лишняя сложность. Очевидно, что теория языков программирования не стояла на месте и пробовали другие подходы, где ошибки старались трактовать «особенно», придумывая для них какие-то новые сущности и инструменты. На практике у каждого подхода есть и плюсы и минусы, причем сильно завязанные на реализации в каждом конкретном языке.

В Go — в духе стремления к простоте, проверенным практикам и дизайну, ориентированному на конкурентные(concurrent) программы — пришли к такому дизайну, в котором используется возврат значений, но лишенный тех минусов, которые были в других языках, и обогащенные особенностями Go. Это быстро, это гибко, это делает очень понятным и простым (пусть и чуть более многословным) код. Так авторы Go видели наилучший подход на тот момент, и многие его находят очень практичным и удобным.
Тогда для чего это называется «ошибкой»?

Потому значение всё же представляет ошибку. Вы же не спрашиваете «почему тип User называется юзером?».
Именно. Ошибка — это такой же полноценный член семьи, как и любой другой. Это значения, в которых вы вольны хранить/передавать делать все что угодно. Насчёт ломки — могу только пожелать быстрее через неё пройти. Сам писал раньше с исключениями, но мне никогда такой подход не был по душе, поэтому Go я быстро принял.
обработка ошибок в Go сделана примерно как в C, только слегка удобнее.

Нет, между Go и C огромные отличия, вы же видите только схожести и делаете выводы только из них.

Можно было бы применить монады

В Go нет монад. В испанском языке нет кириллических букв. Don't fight the language.

Получился в итоге язык, который был бы очень востребован 25 лет назад.

SpaceX, Dropbox, Cloudflare и много других взрослых компаний с вами не согласны.
Так это и есть возвращаемый результат. Но его суть — информация об ошибке.
В принципе, из названий — только интерфейсный тип error, которому может удовлетворять любой тип, имеющий метод Error() string.
E.BS(
E.DS(

Я бы не понял, читая код, что это означает и что там происходит. При беглом взгляде на код (например, code review или знакомство с новым кодом), было бы неясно, как будет программа в данном месте. В первом же варианте — это легко и понятно, будь я вашим коллегой, вы бы облегчили мне сильно жизнь для понимания общего кода.

fmt.Errorf(«User can't send messages»)

Про Errorf уже выше написали, что да, подобные «строковые» ошибки лучше либо выделять в отдельные переменные, либо создавать свой тип. Вообще, мне понравилось предложение из issue по поводу интроспекции ошибок в stdlib:
Если бы я был королем, я бы заставил всех авторов библиотек следовать двум правилам:
— errors.New() использовать только для объявления новых публичных переменных (типа var ErrNoRows ...)
— если вам таки нужно использовать fmt.Errorf() — не используйте, а сделайте кастомный тип для этой ошибки

Очень здравый взгляд, как по мне. Во втором случае имеется ввиду, что Errorf() выполняет некоторое форматирование, значит есть какие-то виды/стейты/данные в этой ошибке -> есть смысл создать типа для этого вида ошибки.
Смотрим на С и, внезапно, видим ровно тоже самое.

Это не тоже самое. Странно, что вы видите только похожие моменты, но не видите концептуальных различий.

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

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

Вот именно эту глупость Go будет из вас выбивать. Именно этот подход так легко насаживается в языках с исключениями, и именно такой взгляд на обработку ошибок приводит, в большинстве своем, к коду в котором нормальной обработки ошибок нет, как понятия. Избавляйтесь от этого убеждения.
Те, кто писал более-менее сложный код на С (в ядре ОС, к примеру), обычно очень хорошо понимают весь ужас C-style error handling.

Некорректно сравнивать C-style и Go-style error handling.
Понятно, что первый поверхностный взгляд увидит некоторую схожесть (вовращаемые значения), но в C ошибки — это не значения, это коды ошибок, и это да, ад. В Go, помимо наличия множественных возвратов, ошибки — это полноценные самодостаточные объекты, и это кардинальная разница.
Ошибка и стектрейс — это разные понятия, их не нужно заменять.
Стектрейс это контекст, его можно получить через runtime.Stack или выбросив panic().
Есть ситуации, когда вам действительно не нужно проверять ошибки. Например, у вас простенькая программка, читающая ввод пользователя из stdin. Вероятностью того, что произойдет какой-то I/O error, который нужно как-то специально обработать, в данном случае можно принебречь. Ровно как и с выводом в stdout. Язык должен стимулировать обрабатывать ошибки, но не запрещать. Кажется, статью очень многие вообще не поняли. На medium-е написал попытку объяснения, переведу на днях.
Это крутая статья, читал в оригинале, но вот интересно было бы пообщаться с теми, кто этот подход к архитектуре реально на практике использует.
Да ладно вам. Вот смотрите, первый комментарий от lair:
Какой механизм не дает программисту забыть вызвать проверку на scanner.Err()?

При этом, я понимаю, что автору не интересно на самом деле разобраться, почему это так и почему, если ему кажется, что это ужасно, SpaceX использует Go, а Dropbox вообще всю инфраструктуру, которая молотит экзабайты данных, тоже переписал на Go. Я знаю, что этот пользователь делает отсылку к давней статье о том, что явная обработка ошибок стимулирует не забывать про ошибки, и пытается тут придумать «минус» языка. При всём при этом, lair, у которого 1 пост и ~8000 комментариев, на Go не пишет, но ходит во все посты к Go и ведет себя точно таким же образом.

Тем не менее, я совершенно спокойно ему отвечаю как есть на его «технический» вопрос:
Документация. Это же библиотека. а не конструкция языка.

И это действительно так. Речь тут о библиотечной функции, с которой, прежде чем воспользоваться, нужно познакомиться — из документации или какой-нибудь статьи, но, в основном, конечно же, из документации. Это не часть языка, это решение библиотеки. Пока что оставим в стороне тот мощный посыл, который несет статья на самом деле, пытаясь объяснить этот момент.

Ну и что мы видим дальше:
И что, это считается хорошим дизайном?

Опять же, отсылка к предыдущим постам об «обсуждении» дизайна Go.
Ну и сами посмотрите на минусы и плюсы.

Кто еще там «хочет понять»? Creker ничего не пытается понять — он пытается доказать, что Go «придумали идиоты» «чтобы было не так, как у других» и это «извращение» и «херота» (цитирую дословно). Это вы называете «люди реально хотят понять»?

Вобщем, мне кажется, вы несколько идеализируете Go-троллей. Я с огромнейшим удовольствием помогаю, всем кому могу, но отличать «хочу понять» и «хочу насадить своё мнение» тоже умею. Хотя да, безусловно, ввязываться в перепалки не стоит, тут уж делаю выводы.
да и как я вижу для обработки ошибок вы сами используете err:=nil ;)

Кажется, хабрачитатели реально не поняли статьи и нужно объяснение.

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

я бы с удовольствием послушал например статья о том, с какими проблемами/ограничениями в Go вы реально столкнулись и как их решили

Я Go принимаю, как есть — без придуманных требований к нему. Он и так мне дал возможность быстро и качественно писать софт, за который я на C++ и даже Python даже не взялся бы, создать свой стартап (только благодаря Go стал возможным, серьезно), и в целом, начать снова получать удовольствие от программирования. Если какие-то есть непонятки — они решаются за минуту и больше не повторяются, каких-то реальных вот «проблем» или «ограничений» я не встречаю.
И всё же, кто от этого страдает?
Ну нет, когда люди, незнакомые с языком, пишут под каждым постом десятки комментариев, пытаясь доказать, что Go неудобен и его придумали извращенцы — это ниразу не «конструктивная критика», уж простите.

Но то, что мне не стоит влазить с ними в перепалки — соглашусь, конечно.
Ну вы же и сами видите в каждом вами предложенном варианте минусы, правда?
Все в плюсе — на хабре больше материала для тех, кто интересуется, и тролли сыты. Win-win.
На Go пишу по работе уже 2.5 года. Несколько open-source проектов есть, конечно же, тоже: github.com/divan

Information

Rating
Does not participate
Location
Barcelona, Barcelona, Испания
Date of birth
Registered
Activity