Я хочу повторно использовать ParseIntError
стандартной библиотеки в своей функции. Однако я сам реализую синтаксический анализ входной строки, поэтому мне не нужно возвращать значение ошибки, возвращаемое стандартной библиотекой.
Я не нашел способ построить значение ParseIntError
. Единственное решение, которое я нашел, выглядит так:
use std::num::ParseIntError;
fn from_str_radix(s: &str, radix: u32) -> Result<(), ParseIntError> {
let error_empty = "".parse::<i32>().expect_err("get empty input error");
let error_invalid_digit = "Z".parse::<i32>().expect_err("get invalid digit error");
if s.is_empty() {
return Err(error_empty);
}
for c in s.chars().rev() {
match c.to_digit(radix) {
None => return Err(error_invalid_digit),
_ => unimplemented!(),
}
}
Ok(())
}
Есть ли более элегантный способ вернуть ParseIntError
из моего собственного кода?
Понимаю. Но, насколько я вижу, это обычная практика повторного использования этого значения ошибки, если используется синтаксический анализ std. Я не понимаю, почему я должен переключаться на свой собственный тип только потому, что я изменил свою внутреннюю реализацию с вызова библиотечной функции на собственный синтаксический анализ.
без минимальный воспроизводимый пример я не могу ответить, вы утверждаете, что «я сам реализую синтаксический анализ входной строки», вы никогда не говорили «я изменил свою внутреннюю реализацию с вызова библиотечной функции на собственный синтаксический анализ» в своем вопросе, поэтому, пожалуйста, редактировать ваш вопрос на включите минимальный воспроизводимый пример и будьте более точны в том, что вы хотите и что вы делаете
Вы можете спровоцировать ту же ошибку, а затем вернуть ее, например. "a".parse::<i32>()?
(не воспринимайте это всерьёз)
@Stargateur, вот запрос на исправление этой проблемы: github.com/rust-lang/rfcs/issues/1143. К сожалению, он открыт с 2015 года и, похоже, никому до него нет дела :-(
Я не думаю, что это было бы хорошо, может быть, вы могли бы использовать ночную функцию, play.rust-lang.org/…. Все еще жду свой минимальный воспроизводимый пример
@Stargateur Спасибо за эту функцию «int_error_matching». Это не решение, а хоть какой-то подход к нему. Пример - я не думаю, что это необходимо здесь. Ситуация уже достаточно ясна: я не могу сам создать ParseIntError, но могу переиспользовать nightly IntErrorKind для своего собственного типа ошибки.
В настоящее время нет возможности создать ParseIntError
самостоятельно. Как вы его обнаружите, есть открытый issue
, который просит сделать его общедоступным. Однако я не думаю, что это хорошо.
ParseIntError
— ошибка модуля num
. Он не предназначен для использования всеми, кто реализует ящик для синтаксического анализа, потому что у вас должен есть собственная потенциальная ошибка. Вы можете использовать IntErrorKind
, но я все еще не думаю, что это хорошо, потому что вы можете закончить без той же ошибки.
Итак, я думаю, у вас должен быть свой собственный тип ошибки и, возможно, использовать тот же дизайн, иметь атрибут enum
с атрибутом #[non_exhaustive]
. Существует множество ящики, которые упрощают создание ошибок. Вы не должны стесняться использовать свою ошибку в собственном коде.
Разве не стоит сделать его пригодным для тестирования?
@WilliamHammond может kind()
и соответствовать IntErrorKind
, если вам это действительно нужно. Или просто is_err()
.
По состоянию на май 2021 года и IntErrorKind, и ParseIntError кажутся общедоступными. doc.rust-lang.org/std/num/struct.ParseIntError.html
@dagilpe нет, ситуация не изменилась, по-прежнему нет возможности самостоятельно Создайте a ParseIntError.
Если вы хотите, чтобы у вас был собственный синтаксический анализ, почему бы вам не использовать свой собственный тип ошибки?
ParseIntError
не использует общедоступный конструктор, а его поле является закрытым. Так что ты не можешь