Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
scanner := bufio.NewScanner(input)
for scanner.Scan() {
token := scanner.Text()
// process token
}
if err := scanner.Err(); err != nil {
// process the error
}
scanner.Err()?Какой механизм не дает программисту забыть вызвать проверку на scanner.Err()?
Документация. Это же библиотека. а не конструкция языка.
И это считается хорошим дизайном?
Мне говорят, что надо не сразу получать ошибку и ее обрабатывать, а пробежаться все сотни и миллионы итераций с no-op
Это херота какая-то и ужасный просто совет
Вам так не говорят. В статье рассматривается конкретный пример.
а пробежаться все сотни и миллионы итераций с no-op
Мне прямым текстом говорят, что один вариант плохой, а другой хороший
В существующем же дизайне API, пользовательский код таким образом выглядит более естественным: сначала пройтись до конца по токенам, а потом проверять и волноваться об ошибках. Обработка ошибок не прячет поток управления.
Под капотом всего этого, конечно, происходит следующее — как только Scan обнаруживает ошибку ввода-вывода, она сохраняет ошибку и возвращает false. Отдельный метод, Err, её возвращает, когда клиент запросит
он широко используется и в других языках, в частности в С
{DATA_FETCHED, EOF, ERROR}.while Scanner.Scan()==DATA_FETCHED), но из интерфейса было бы кристально понятно, что может быть как ERROR, так и EOF, не надо смешивать эти ситуацииНо зачастую, подход всё-или-ничего в конце бывает достаточным.
errno, содержащая последний код ошибки, объявляется со спецификатором __thread. Операционная система помещает эти переменные на страницу памяти, в которую при переключении потока мапится физическая страница с переменными конкретного потока, каждый поток имеет свою версию errno.Ну так напишите какая у статьи тема, чём посыл и какой сделан вывод.
Статья о другом, у нее абсолютно другая тема, другой посыл и другой вывод.
Err — и никогда никогда об ошибке не узнает.как обычно есть одно «но», когда вы проигнорировали вообще весь результат функции
scanner := bufio.NewScanner(input)
for scanner.Scan() {
token := scanner.Text()
// process token
}
Ну и в доке сразу правильный пример идет как ошибку обработать.
И декларация кстати в том, что ошибка идет вместе с результатом, чтобы вы их не разделяли. и тут получается что результат у нас токен, а он лежит внутри структуры парсера, там же где ошибка иии формально все классно…
То есть, нашли пакет, конструктор, у типа нашли метод, нужный, поняли что его надо в условие цикла поставить, и вызывать Token у сканера, не прочитав ни доки, ни описания к методам ни их кода. И с такой проницательностью не поняли что там есть Err?!
Вы понимаете, реально как человеку который пишет на Go мне слух режут все эти разговоры, о 100500 мега ппц важных проблем которых для меня как человека который почти каждый день на нем пишет на самом деле нет.
Вот чуть расширенный подход, где возвращается тип токена, а не bool godoc.org/golang.org/x/net/html
так лучше, или все равно плохо?
Это не 4 типа сообщать об ошибках, т.к. вы Err() посчитали дважды (или для вас bool в Scan и TokenType в Next() это 2 разных способа сообщать об ошибках?!)
Scan сообщает не об ошибке, а о прекращении прохода (а уж причину будь ласка узнавать из Err).Может у вас есть пример как сделать дизайн токинизаторов (лексических парсеров) лучше?
Reader.ReadString возвращает (string, error), но Scanner.Scan возвращает bool, а за ошибкой идите в другую сторону. Хотя и то, и другое можно использовать для построчного чтения файла.Scan может вернуть false (т.е., по вашему мнению, индикатор ошибки) даже в том случае, когда Err вернет nil (т.е., ошибки не было) — это случится в конце потока. Поэтому индикатором именно наличия ошибки служит сравнение Err с nilf, err := os.Open("filename.ext")
if err != nil {
log.Fatal(err)
}
bufio же из стандартной библиотеки, я ничего не путаю?), где ошибку легко можно проигноровать.Зато я вот заметил другое — в Go людям плевать на ошибки.Вам целую статью написали, что не плевать.
И мне здесь уже советовали плевать на ошибки. Все равно их все не обработать.Это просто неправда, либо люди не компетентны либо вы неправильно их поняли, исказив смысл под своё мнение. Вот цитата из документации к bufio/scanner:
я вижу метод с ошибкой и сразу пишу, что мне делать, что там за ошибка мне в принципе не очень то и важно.
3) спасибо конечно… но я как бы догадался…
То есть как видим и коды и текст разные.
2) она не поможет если вы попали в этот 0.1%
Такое ощущение, что сделали лишь бы чтобы было по-другому.
Все аргументы,… не выдерживают критики.
Кто ее обрабатывает? Да никто. Это прям как коды ошибок в C.
Panic и recovery не более чем костыль
но похоже намерено сделаны уродливыми и неудобными, чтобы их по-меньше использовали.
Я понимаю, что можно посмотреть исходник, но это, извините, полное извращение
Вы вправду верите, что Go делали, руководствуясь такими соображениями?
Выдерживают.
Опять 25. Panic — именно та ситуация, когда произошла неотвратимая ошибка, и нужно завершить программу и вывалить стек.
Это ваши неверные догадки. Не знаю, почему вы не хотите разобраться в истинных причинах.
Это в других языках извращение. В Go исходники всегда доступны в godoc и это вопрос миллисекунд. Попробуйте, прежде чем судить.
Но вообще, хорошую идею подали. Хотя подобная ситуация никогда в практике не была проблемой, но это интересный кейс для статического анализа.
Вы вправду верите, что Go делали, руководствуясь такими соображениями?
Приходится, потому что объективных причин нет
Ага, при этом в Go игнорирование ошибки это поведение по-умолчанию
Panic рекомендуется использовать в тех же библиотеках, есть даже конкретный паттерн, который приводится в пример
Нет объективных преимуществ у Go ошибок.
Тот же рандомизированный select — явно намекают, что не надо тебе надеяться, чтобы кто-то будет первый.
Ты лучше архитектуру поменяй, чтобы этого не требовалось.
Это извращение и никак иначе.
Так все таки вы ребенок
Задача авторов языка и вас, как его самопровозглашенного защитника, показать
Ни авторы языка
не пишите, что это «херота» и «полное извращение и никак иначе».
Параллельно с этим вы ещё на людей кидаетесь, пытаясь их оскорблять
И конкретно дизайн ошибок меня ничем не убедил, что он чем-то лучше.
я написал конкретно почему. Что вы мне ответили? «Выдерживают».
и выражаю это в культурной… форме такими словами как «херота» и «извращение»
Почему вас кто-то в чём то должен убеждать?
Если вы настолько привыкли к эксепшенам, что готовы свято отстаивать их, переходить на личности и писать простыни гнева
простыни гнева
Вы обманываете себя. Вы написали без доводов «Не выдерживают критики». Я, чтобы подчеркнуть несостоятельность такого аргумента, вам парировал — «Выдерживают».
У нас разные представления о культуре.
Мата нет — значит культурная форма.
да и как я вижу для обработки ошибок вы сами используете err:=nil ;)
я бы с удовольствием послушал например статья о том, с какими проблемами/ограничениями в Go вы реально столкнулись и как их решили
Какой механизм не дает программисту забыть вызвать проверку на scanner.Err()?
Документация. Это же библиотека. а не конструкция языка.
И что, это считается хорошим дизайном?
у Go очень подробные трейсы, если у вас получилось что не обработали ошибку сильно не в том месте где упало, смотрите на это как на стимул обрабатывать ошибки.
Подход с ошибками можно описать просто — я вижу метод с ошибкой и сразу пишу, что мне делать, что там за ошибка мне в принципе не очень то и важно.
99% ошибок в go это errors.New(«some text»)
какой use case, что именно вы смотрите кроме текстовки и как на это реагируете?
на что угодно но не на тип, либо сравнение с переменной вроде io.EOF, либо каст к интерфейсу вроде net.Error.
да? то есть вы будете перечислять все ошибки почему не получилось забиндить порт? а если вдруг за будите какую?
Недавно мы просканировали все open-source проекты, которые мы только смогли найти и увидели, что этот сниппет появляется лишь раз на страницу или две, гораздо реже, чем многие могли бы подумать.Видимо многие игнорируют ошибки и пишут «не безопасный» код.
Ошибки — это значения