тут уже давали ссылку blog.golang.org/errors-are-values, в парсерах в go в том числе и в пакетах от google применяется так называемый errReader/errWriter
это обертка над стандартными Reader/Writer которая сохраняет err, тоесть если вы просто вызываете 5 методов Write и если на втором например произойдет ошибка, то остальные не выполняться, а вы после них всех проверите свойство у объекта writer.err() != nil
а почему наличие встроенной многозадачности должно делать язык нишевым? Erlang нишевый не поэтому. А Go вообще не является нишевым (выше уже приводил пример docker)
про GC — а сколько вы знаете компилируемых языков со сборщиком мусора?
я правильно понимаю, что Akka это по сути брокер сообщений?
Go и Erlang создавались чтобы быть многопоточными изначально, чтобы создавать сотни тысяч потоков и не убивать при этом сервер, чтобы это было очень легко делать из коробки, под все платформы и это именно повод к их созданию, потому что в других языках этого нет.
Я не очень понимаю против чего именно вы протестуете? что эти языки не нужны или что?
вот есть у вас список подключенных клиентов, вы захотели его сохранить на диск, заблочили его на запись, начали сохранять и не смогли записать на диск — место кончилось.
Никакие Rall тут не спасут, (в go кстати нет деструкторов в классическом виде, хотя можно повесить хук на удаление объета)
ну революционности нет, взяли то что использовалось в C++ годами только вместо кода возврата, можно возвращать nil или объект который точно может вернуть описание того что пошло не так
ну и доп. информацию (как например выше кидали информацию про таймаут) при желании
горутины это часть языка, и то что есть как минимум 2 языка в которых это (встроенная многопоточность) сделано уже должно наводить на мысль что это кому нибуть нужно
это в частности позволяет легко распараллеливание обработку и использовать их повсеместно, для многих задач. не ограничиваясь тем для чего вы это используете — для реализации асинхронного взаимодействия или вам нужно ускорить вычисления заняв несколько ядер процессора.
пример про Scala не показателен, я с тем же успехом я могу написать, классы не нужны, вон в скала xml добавили теперь выпилить не могут
у нормальных языков есть стандарт который не только описывает что можно делать в языке, а что нет, но и как это делать — чтобы программы одинаково работали при компиляции разными компиляторами.
Почему? Для Си нельзя написать виртуальную машину? Причем тут язык-то?
При чем здесь виртуальная машина и сборщик мусора?
У меня нет никаких сомнений, что справляется, потому что средства работы с исключениями Go аналогичны таковым в большинстве современных ЯП.
Ну легковесные потоки и GC не имеют отношения к языку как таковому, на мой взгляд. Думаю, такие вещи в принципе можно реализовать для любого языка.
Про потоки — на вскидку я могу назвать только 2 языка в которых это сделано частью стандартного синтаксиса это Go и Erlang, тоесть чтобы запустить новый поток нужно написать go, spawn и всё.
про GC, на примере того же C/C++ я себе это слабо представляю
Обработка ошибок это то что по сути было в C++ — если что-то аномальное то исключение, если предусмотренный случай то это соответствующий код возврата.
При создании языка решали вполне конкретные проблемы, которые всплыли в процессе разработки в Google на разных языках и Go с этим справляется, что будет дальше покажет время
> достаточно одного try-catch
> при этом весь сервер будет работать стабильно.
это не так, вы же не hello world возвращаете, при работе много поточного приложения есть доступ к общим объектам, теже блокировки например, так вот если что-то пошло не так вы должно сделать Unlock, иначе у вас приложение не сможет дальше работать, так что 1 try/catch явно мало
> И это всего 2 try-catch, вместо тысячи проверок каждого вызова.
а почему не миллион? недавно была статья про рекомендации НАСА к кода, там не только результат проверяется, но и насколько результат соотвестует допустимым границам и так для каждого вызова (а в Go только для тех что error возвращают)
> И это правильно, нельзя работать после ошибки, иначе будут непредсказуемые последствия, зачем пытаться читать из файла если не смог его открыть? Но если все же хочется, то это можно сделать.
ошибки бывают разные, программы не только открывают файлы (см. внизу)
> и тут приложение выпадает в crash, если вдруг произойдет чтение из чужой области памяти
да упадет и в Go если вы сможете такое сделать это будет panic, так как вы допустили такое и после этого
еще раз напишу — в Go для действительно исключительных ситуаций есть panic — это считайте те же исключения, для того что предусмотрено и что должно обрабатываться в вашем коде используется error
если вы запрашиваете элемент 5 у массива с 2 элементами это panic — вы не правильно написали программу, она не работает, если вы не смогли скачать файл — это error потому что это нормальная ситуация, и вы должны принять решение что делать дальше, прямо в том месте где вы его скачивали, сохранить половину и попытаться еще раз, удалить и т.п., если вы не можете принять этого решения (например вы пишите библиотеку) — вы возвращаете этот error из своего метода, и тот кто будет пользоваться вашей библиотекой, в свою очередь опять примет решение, какое решение принять, это часть нормальной работы
можно в обоих случаях писать err вместо err1 и err2
делать панику из-за обыденной ситуации не правильно, error Это часть логики работы, это нормальное поведение panic — это не нормальное поведение, по сути свидетельствующее что программа написана не правильно, и так как без человека не понять где что-то пошло не так, нужно падать так далеко по стеку вызовов насколько позволят (recover)
Т.е. try-catch по сути делает тоже самое, только дефолтное поведение — это передача ошибки наверх, как отписались выше это то что нужно в 90% случаев.
если у вас задача падать то да, а вот если работать, то обрабатывать ошибки придется, и вот тогда у вас этих try/catch будет огого как много.
При использовании исключений если вы ее не поймате сразу же то может статься что её поймают где-то в глобальном catch всего приложения, и продолжить выполнение вы уже не сможете.
error в Go это не исключительная ситуация, это часть работы приложения, исходя из того что вы вызываете вы сами принимаете решение что делать, с ошибками, например если вы файл по сети читаете то их нужно обрабатывать, а если вы сделали Reader (стандарный интерфейс для чтения потока с 1 методом Read() ([]byte, error)) из куска оперативы, то там и обрабатывать нечего.
> Дефолтное поведение в golang — это видимо «забить» на ошибку, + авторы строго рекомендуют использовать 2 и 3 варианты.
его нет, error это часть результата некой функции, как из 3х вариантов выбрать придется прописать явно*
* строго говоря есть 1 случай когда error это единственный результат работы функции и тогда можно просто написать вызов (_ := писать не заставляют)
да в Rust вариант более строгий, хотя смысл очень похож:
if file, err := os.Open("foo.txt"); err == nil {
// здесь код, который может работать с файлом
} else {
// здесь можно вывести сообщение об ошибке
}
// здесь нет ни file ни err
только строчек примерно в 2 раза меньше, ну и как я писал в обоих случаях можно работать с результатом
результаты и ошибки тоже разные бывают, например если это Read() ([]byte, error) то []byte может содержать байты прочитанные до возникновения ошибки
а про file -обратится можно, только там nil будет
на самом деле в Go нет ничего чтобы было сделано именно для обработки ошибок: возврат нескольких значений, короткий синтаксис объявления переменных, возможность пропустить значение при присваивании нескольких значений — все это общие конструкции.
Как я писал выше Go не заставляет обрабатывать ошибки, но он уберегает (в большинстве случаев) когда вы можете забыть это сделать, во всех случаях вы сами приняли решение что делать с ошибкой: игнорировать, обработать, или вернуть выше.
ну enterprise это очень широкое понятие начиная от потребностей гугл, заканчивая софтом для тестирования учащихся в школе.
Go используется на вскидку в гугл, фейсбук, яндекс, и из самого известного софта на go это docker, так что кое что уже успели написать
а чтобы за 3 года после выхода все было бы заполнено софтом написанным на go — это он сам должен за программиста писать тогда
энтерпрайз это годы разработки, первая публичная версия Go появилась меньше 4х лет назад, версия 1.0 зарелизилась меньше 3х лет назад
его просто не успели еще написать
вы передергиваете, писать обработку нужно только там где это необходимо, если не нужно обрабатывать делаете return этой ошибки, тоесть в момент написания кода вас подтолкнули принять решение, вернуть ошибку, обработать или забить (через _) и вы его приняли.
Если тот код который вы вызываете не возвращает error то тоже не нужно ничего обрабатывать.
> file3=os.Open(«test2.txt») | errHandler3(HANDLE_AND_EXIT_CUR_FUNCTION,ER_CODE)
вообще для того чтобы что-то возвращать нужно иметь соответствующее объявление функции
это обертка над стандартными Reader/Writer которая сохраняет err, тоесть если вы просто вызываете 5 методов Write и если на втором например произойдет ошибка, то остальные не выполняться, а вы после них всех проверите свойство у объекта writer.err() != nil
про GC — а сколько вы знаете компилируемых языков со сборщиком мусора?
я правильно понимаю, что Akka это по сути брокер сообщений?
Я не очень понимаю против чего именно вы протестуете? что эти языки не нужны или что?
Никакие Rall тут не спасут, (в go кстати нет деструкторов в классическом виде, хотя можно повесить хук на удаление объета)
ну и доп. информацию (как например выше кидали информацию про таймаут) при желании
это в частности позволяет легко распараллеливание обработку и использовать их повсеместно, для многих задач. не ограничиваясь тем для чего вы это используете — для реализации асинхронного взаимодействия или вам нужно ускорить вычисления заняв несколько ядер процессора.
пример про Scala не показателен, я с тем же успехом я могу написать, классы не нужны, вон в скала xml добавили теперь выпилить не могут
При чем здесь виртуальная машина и сборщик мусора?
Это касалось не только (и не столько) исключений
Про потоки — на вскидку я могу назвать только 2 языка в которых это сделано частью стандартного синтаксиса это Go и Erlang, тоесть чтобы запустить новый поток нужно написать go, spawn и всё.
про GC, на примере того же C/C++ я себе это слабо представляю
Обработка ошибок это то что по сути было в C++ — если что-то аномальное то исключение, если предусмотренный случай то это соответствующий код возврата.
При создании языка решали вполне конкретные проблемы, которые всплыли в процессе разработки в Google на разных языках и Go с этим справляется, что будет дальше покажет время
> при этом весь сервер будет работать стабильно.
это не так, вы же не hello world возвращаете, при работе много поточного приложения есть доступ к общим объектам, теже блокировки например, так вот если что-то пошло не так вы должно сделать Unlock, иначе у вас приложение не сможет дальше работать, так что 1 try/catch явно мало
> И это всего 2 try-catch, вместо тысячи проверок каждого вызова.
а почему не миллион? недавно была статья про рекомендации НАСА к кода, там не только результат проверяется, но и насколько результат соотвестует допустимым границам и так для каждого вызова (а в Go только для тех что error возвращают)
> И это правильно, нельзя работать после ошибки, иначе будут непредсказуемые последствия, зачем пытаться читать из файла если не смог его открыть? Но если все же хочется, то это можно сделать.
ошибки бывают разные, программы не только открывают файлы (см. внизу)
> и тут приложение выпадает в crash, если вдруг произойдет чтение из чужой области памяти
да упадет и в Go если вы сможете такое сделать это будет panic, так как вы допустили такое и после этого
еще раз напишу — в Go для действительно исключительных ситуаций есть panic — это считайте те же исключения, для того что предусмотрено и что должно обрабатываться в вашем коде используется error
если вы запрашиваете элемент 5 у массива с 2 элементами это panic — вы не правильно написали программу, она не работает, если вы не смогли скачать файл — это error потому что это нормальная ситуация, и вы должны принять решение что делать дальше, прямо в том месте где вы его скачивали, сохранить половину и попытаться еще раз, удалить и т.п., если вы не можете принять этого решения (например вы пишите библиотеку) — вы возвращаете этот error из своего метода, и тот кто будет пользоваться вашей библиотекой, в свою очередь опять примет решение, какое решение принять, это часть нормальной работы
делать панику из-за обыденной ситуации не правильно, error Это часть логики работы, это нормальное поведение panic — это не нормальное поведение, по сути свидетельствующее что программа написана не правильно, и так как без человека не понять где что-то пошло не так, нужно падать так далеко по стеку вызовов насколько позволят (recover)
если у вас задача падать то да, а вот если работать, то обрабатывать ошибки придется, и вот тогда у вас этих try/catch будет огого как много.
При использовании исключений если вы ее не поймате сразу же то может статься что её поймают где-то в глобальном catch всего приложения, и продолжить выполнение вы уже не сможете.
error в Go это не исключительная ситуация, это часть работы приложения, исходя из того что вы вызываете вы сами принимаете решение что делать, с ошибками, например если вы файл по сети читаете то их нужно обрабатывать, а если вы сделали Reader (стандарный интерфейс для чтения потока с 1 методом Read() ([]byte, error)) из куска оперативы, то там и обрабатывать нечего.
> Дефолтное поведение в golang — это видимо «забить» на ошибку, + авторы строго рекомендуют использовать 2 и 3 варианты.
его нет, error это часть результата некой функции, как из 3х вариантов выбрать придется прописать явно*
* строго говоря есть 1 случай когда error это единственный результат работы функции и тогда можно просто написать вызов (_ := писать не заставляют)
только строчек примерно в 2 раза меньше, ну и как я писал в обоих случаях можно работать с результатом
а про file -обратится можно, только там nil будет
на самом деле в Go нет ничего чтобы было сделано именно для обработки ошибок: возврат нескольких значений, короткий синтаксис объявления переменных, возможность пропустить значение при присваивании нескольких значений — все это общие конструкции.
Как я писал выше Go не заставляет обрабатывать ошибки, но он уберегает (в большинстве случаев) когда вы можете забыть это сделать, во всех случаях вы сами приняли решение что делать с ошибкой: игнорировать, обработать, или вернуть выше.
Go используется на вскидку в гугл, фейсбук, яндекс, и из самого известного софта на go это docker, так что кое что уже успели написать
а чтобы за 3 года после выхода все было бы заполнено софтом написанным на go — это он сам должен за программиста писать тогда
его просто не успели еще написать
Если тот код который вы вызываете не возвращает error то тоже не нужно ничего обрабатывать.
всё что вы написали псевдокодом с кущей констант уже есть:
> file1=os.Open(«test1.txt») | someErrorHandler(HANDLE_AND_EXIT)
> file2=os.Open(«log.txt») | someErrorHandler2(HANDLE_AND_CONTINUE)
> file3=os.Open(«test2.txt») | errHandler3(HANDLE_AND_EXIT_CUR_FUNCTION,ER_CODE)
вообще для того чтобы что-то возвращать нужно иметь соответствующее объявление функции
play.golang.org/p/RRwRPhrH5j