Черта Num
, определенная в num crate , должна отвечать вашим потребностям, но то, что вы пытаетесь сделать, не является идиоматическим в Rust, поэтому я хотел бы предложить два предложения:
- В некоторых языках, таких как C, например, традиционно перегружают определенные значения, такие как 0 или -1, специальными значениями, но было показано, что это является источником путаницы и даже серьезных ошибок.
Вместо этого рассмотрите возможность использования типа Result<T, E>
, если ваша функция может не вернуть результат по нескольким причинам, или типа Option<T>
, если существует ровно одна причина, по которой ваша функция не может вернуть результат.
В вашем случае вы можете использовать Result<T, E>
, чтобы ваша функция могла сообщить, почему преобразование не удалось - содержалась ли строка недопустимых числовых символов? Было ли значение вне диапазона для запрашиваемого типа? Вызывающие абоненты вашей функции, возможно, должны знать, чтобы иметь возможность лучше справляться с ситуацией.
- Стандартная библиотека Rust уже включает в себя требуемую функциональность (преобразование строк в значение через универсальную реализацию) в виде
std::string::String::parse()
или str::parse()
методы. По причинам, указанным выше, эти методы действительно возвращают Result
.
Используя две вышеуказанные части информации, ваш код теперь можно переписать более надежно, как показано ниже (используя Rust 1.26+ для упрощения обработки ошибок):
type Result<T> = std::result::Result<T, Box<std::error::Error>>;
fn main() -> Result<()> {
let num_str = String::from("12");
println!("Converted to i32: {}", num_str.parse::<i32>()?);
Ok(())
}
пример детской площадки
В случае возникновения проблемы обратите внимание на то, как приятно сообщать об ошибках:
type Result<T> = std::result::Result<T, Box<std::error::Error>>;
fn main() -> Result<()> {
let num_str = "-1";
println!("Invalid u32 conversion: {}", num_str.parse::<u32>()?);
Ok(())
}
пример детской площадки
Это выводит Error: ParseIntError { kind: InvalidDigit }
на консоль и возвращает значение std::libc::EXIT_FAILURE
вызывающему процессу (означающему, что программа завершилась с ошибкой), все без перегрузки значений или "магических чисел".