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

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

Send message
Да, хорошая статья, она тут уже в комментариях проскакивала. )
Гарантий нет, конечно же, но есть два важных отличия у Go:
1) авторы считают «обратно несовместимые» изменения злейшим злом, и будут стремиться делать все возможное, чтобы даже их не было даже в мажорных версиях
2) Go это не эксперимент в стиле «давайте создадим еще один фичастый язык». После публичного анонса языка и до версии 1.0 изменения были минимальны — базис Go был изначально очень фундаментально продуман и лишь слегка обрастал и менялся до релиза 1.0. Такого треша как в Rust — когда половина всего выбрасывается, переписывается и чистится уже который раз подряд — в Go не было и не будет.

Исходя из этого, я более чем уверен, что если даже когда либо и будет Go2 (а это уж точно не ближайшие 3 года, его даже в roadmap-е нет), то в нем не будет изменений в стиле «открывать файлы через os.Open() теперь не правильно».
Плохо, конечно же. Глобальные переменные, даже read-only (а логгер не является read-only), имеют много скрытых проблем. По этой теме книжки можно писать. Как только ваша программа будет расти, и с ней будут работать другие люди, в том числе, писать тесты и рефакторить — этот ваш логгер в виде глобальной переменной быстро станет источником потенциальных проблем и геммороя.

Я потерял нить дискуссии.
Вы хотите сказать, что явный возврат ошибок подталкивает к тому, что программист будет их игнорировать и аппелируете к опыту в vbscript? Это, кстати, частый аргумент в спорах о Go — «я уже видел подобное в Java/VB/C#/Python/whatever и считаю, что это плохо». Нюанс в том, что в Go это сделано иначе и детали решают. Например, не будь при всем этом «обязательной проверки неиспользованных переменных» — вся эта конструкция с возвратом err была бы не ценнее, чем возврат кодов ошибок в C.

Ну и правда в том, что реальность иная — люди не игнорируют ошибки в Go. Возможно я упускаю какие-то другие причины, но в Go считается дурным тоном игнорировать обработку ошибок. Для интереса можно прогнать утилиту errcheck по всем open-source проектам на Go и сравнить :)
«Энтерпрайз системы» — это всего лишь прикладные программы в очень большом масштабе.
Java, да, к сожалению много ниш заняла — по крайней мере системный/серверный софт и командные утилиты на ней пишут.
Ну, мне хватило опыта подобных дискуссий :)
Есть люди, которые считают, что «чем сложнее, тем лучше, нужно просто научиться» и все доводы этой статьи им будут смешны.

Но заставлять кодера маниакально писать анализ после каждого оператора… Крайность же, возведённая в стандарт ))

Не заставлять. Если кодер сильно хочет и считает, что он прав — он может заглушить обработку ошибки, но это остается на его совести. В конце концов, хороший программист и отличается от плохого тем, что знает, когда можно забить на проверку ошибки, а когда нет ;-)
Понятно. Вот за это я отдельно люблю Go — за обещание не ломать API.

Многие языки, вводя новые изменения, создают просто месиво из «правильно» и «неправильно» (в угоду обратной совместимости, конечно же). 3 года проходит — и всё, половина из того, что ты знал и как делал — уже неправильно и не кошерно :)
Зависит от того, для чего переменная. Если это, скажем, дескриптор сокета/базы-данных/mongo-сессии/whatever, который используется в запросах бекенда — то явно нужно его заворачивать в некий контекст, и уже его передавать функциями, работающими с этим. Если это некое значение по умолчанию — то либо в константу, либо в конфиг, либо в параметр командной строки (как пример). Если это переменная, описывающая состояние state-машины — то избавиться от такой переменной вообще. Ну и в таком духе.
Зачем закрывать файл «вне зависимости»? Исключение выбросится, если файла не существует и он и не был открыт.

Сути ваш пример не меняет — в нем на обработку ошибок забито по принципу «python сам все разрулит». Потому что это легко и просто.
Ну, я сравнивал языки, которые претендуют на примерно одну и ту же нишу.

Не очень понял, что вы подразумеваете под «эстетическим компонентом». Мой поинт был в том, что подход Go делает сложным «забивать на обработку ошибок», а это приводит к тому, что программист так или иначе начинает быть более внимательным к этому аспекту разработки.
Конечно. Ошибка — не означает автоматически, что нужно завершить функцию. Если ошибка некритична — возможно нужно просто записать в лог, или подставить дефолтное значение, или попробовать fallback-метод. Тонна вариантов и явный возврат ошибок делает обработку гибче и яснее.

Но я не хочу развивать тему exceptions vs return-values — поинт статьи был несколько в другом. Решения дизайна по Go принимал не я, в конце концов. :)
Ну, про «сократить» число проверок уже обсудили комментом ниже. Код, в котором вызывается 10 раз подряд одна и та же функция, ошибки от которой нужно обрабатывать абсолютно одинаково — то да, исключения дают более читабельный код. Нюанс в том, что такой код редко встречается, и если и встречается — то это повод для рефакторинга.

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

Под «читабельностью программы» я подразумеваю количество времени и усилий необходимых понять, как именно работает код, при этом, как уже упоминалсь в некоторых комментариях — важно понимать, что «обработка ошибок» — это неотъемлимая часть программы, а не опциональная.

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

Но главная беда все же в другом — а именно в том, что вот эта легкость «не обрабатывать ошибку, а просто выбросить эксепшн или разобраться потом» создает стимул для того, чтобы именно так и поступать. Именно поэтому для правильного использования исключений в реальном мире вам нужны «программисты со стажем не менее 5 лет» и толстые книжки. И именно поэтому большая часть кода, который я видел в своей жизни — использует исключения далеко не так эффективно, как это описывают адепты исключений.
Не должна, а может содержать. В Java поддерживаются как checked- так и unchecked-исключения.
Некоторые считают, что это добавило (ещё больше) проблем и геммороя в Java-мире: blog.informatech.cr/2014/04/04/jdk-8-interface-pollution/
Хотя инициатива была, конечно, из благих побуждений.
golang.org/ref/spec#Defer_statements

A «defer» statement invokes a function whose execution is deferred to the moment the surrounding function returns, either because the surrounding function executed a return statement, reached the end of its function body, or because the corresponding goroutine is panicking.


анонимная функция в данном случае ничем не отличается от обычной функции
+1
Это к вопросу о том, что обработка ошибок — такая же полноценная часть программы, а не что-то отвлекающее, что нужно спрятать подальше. В данном примере соблазнительность метода «завернуть все в блок try..catch… и язык все сам разрулит» очень легко порождает подобные ошибки, да.
Еще хуже — file закроется при выходе из замыкания :)
Именно, для двух повторений оно того не стоит.
А вот если нужно с десяток однотипных вызовов-и-проверко делать — то стоит.

Еще можно в вашем примере в замыкании возвращать func(), которая будет использоваться для defer в основной функции. Сейчас код не соберется изза defer file1.Close().
Вот тут Dave Chaney интересную методологию авторам библиотек предлагает — dave.cheney.net/2014/12/24/inspecting-errors — для популярных типов ошибок (вроде Timeout или Temporary Error) реализовывать соответствующие интерфейсы, а не просто передавать значения. Не знаю, правда, подхвати ли эту идею кто-то или нет.
Нет, лучше себя приучать писать код так, как будто он выложен в паблик и на него смотрит весь мир. Хорошая практика.
А 'go fmt' включенный по-умолчанию при сохранении исходника — этому помогает, правда. Попробуйте, через недельку не поймете, как можно было без этого жить :)
Вот — это оно.

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

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

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

Information

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