Как создать ParseIntError в моем собственном коде?

Я хочу повторно использовать 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 из моего собственного кода?

Если вы хотите, чтобы у вас был собственный синтаксический анализ, почему бы вам не использовать свой собственный тип ошибки? ParseIntError не использует общедоступный конструктор, а его поле является закрытым. Так что ты не можешь

Stargateur 08.04.2019 13:15

Понимаю. Но, насколько я вижу, это обычная практика повторного использования этого значения ошибки, если используется синтаксический анализ std. Я не понимаю, почему я должен переключаться на свой собственный тип только потому, что я изменил свою внутреннюю реализацию с вызова библиотечной функции на собственный синтаксический анализ.

Michael Ilyin 08.04.2019 13:18

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

Stargateur 08.04.2019 13:23

Вы можете спровоцировать ту же ошибку, а затем вернуть ее, например. "a".parse::<i32>()? (не воспринимайте это всерьёз)

hellow 08.04.2019 13:23

@Stargateur, вот запрос на исправление этой проблемы: github.com/rust-lang/rfcs/issues/1143. К сожалению, он открыт с 2015 года и, похоже, никому до него нет дела :-(

Michael Ilyin 08.04.2019 13:45

Я не думаю, что это было бы хорошо, может быть, вы могли бы использовать ночную функцию, play.rust-lang.org/…. Все еще жду свой минимальный воспроизводимый пример

Stargateur 08.04.2019 13:53

@Stargateur Спасибо за эту функцию «int_error_matching». Это не решение, а хоть какой-то подход к нему. Пример - я не думаю, что это необходимо здесь. Ситуация уже достаточно ясна: я не могу сам создать ParseIntError, но могу переиспользовать nightly IntErrorKind для своего собственного типа ошибки.

Michael Ilyin 08.04.2019 14:21
Знайте свои исключения!
Знайте свои исключения!
В Java исключение - это событие, возникающее во время выполнения программы, которое нарушает нормальный ход выполнения инструкций программы. Когда...
4
7
1 958
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

В настоящее время нет возможности создать ParseIntError самостоятельно. Как вы его обнаружите, есть открытый issue, который просит сделать его общедоступным. Однако я не думаю, что это хорошо.

ParseIntError — ошибка модуля num. Он не предназначен для использования всеми, кто реализует ящик для синтаксического анализа, потому что у вас должен есть собственная потенциальная ошибка. Вы можете использовать IntErrorKind, но я все еще не думаю, что это хорошо, потому что вы можете закончить без той же ошибки.

Итак, я думаю, у вас должен быть свой собственный тип ошибки и, возможно, использовать тот же дизайн, иметь атрибут enum с атрибутом #[non_exhaustive]. Существует множество ящики, которые упрощают создание ошибок. Вы не должны стесняться использовать свою ошибку в собственном коде.

Разве не стоит сделать его пригодным для тестирования?

William Hammond 20.04.2021 03:23

@WilliamHammond может kind() и соответствовать IntErrorKind, если вам это действительно нужно. Или просто is_err().

Stargateur 20.04.2021 06:00

По состоянию на май 2021 года и IntErrorKind, и ParseIntError кажутся общедоступными. doc.rust-lang.org/std/num/struct.ParseIntError.html

dagilpe 23.05.2021 17:47

@dagilpe нет, ситуация не изменилась, по-прежнему нет возможности самостоятельно Создайте a ParseIntError.

Stargateur 23.05.2021 19:45

Другие вопросы по теме