Трейт FromStr
#![allow(unused)] fn main() { pub trait FromStr: Sized { type Err; // Обязательный метод fn from_str(s: &str) -> Result<Self, Self::Err>; } }
Парсинг значения из строки
Метод from_str трейта FromStr часто используется неявно через метод parse типа str. Примеры смотрите в документации к parse.
FromStr не имеет параметра времени жизни, поэтому можно парсить только типы, которые сами не содержат параметра времени жизни. Другими словами, можно распарсить i32 с помощью FromStr, но не &i32. Можно распарсить структуру, содержащую i32, но не ту, что содержит &i32.
Формат ввода и круговая конверсия (round-tripping)
Формат ввода, ожидаемый реализацией FromStr для типа, зависит от самого типа. Проверяйте документацию по конкретному типу для ознакомления с форматами ввода, которые он умеет парсить. Обратите внимание, что формат ввода реализации FromStr для типа может не обязательно принимать формат вывода его реализации Display. Даже если это так, реализация Display может не быть lossless (без потерь), поэтому круговая конверсия может потерять информацию.
Однако, если тип имеет lossless реализацию Display, вывод которой предназначен для удобного машинного парсинга, а не только для восприятия человеком, то тип может принимать тот же формат в FromStr, и это должно быть задокументировано. Наличие реализаций Display и FromStr, где результат Display нельзя распарсить с помощью FromStr, может удивить пользователей.
Примеры
Базовая реализация FromStr для примера типа Point:
#![allow(unused)] fn main() { use std::str::FromStr; #[derive(Debug, PartialEq)] struct Point { x: i32, y: i32 } #[derive(Debug, PartialEq, Eq)] struct ParsePointError; impl FromStr for Point { type Err = ParsePointError; fn from_str(s: &str) -> Result<Self, Self::Err> { let (x, y) = s .strip_prefix('(') .and_then(|s| s.strip_suffix(')')) .and_then(|s| s.split_once(',')) .ok_or(ParsePointError)?; let x_fromstr = x.parse::<i32>().map_err(|_| ParsePointError)?; let y_fromstr = y.parse::<i32>().map_err(|_| ParsePointError)?; Ok(Point { x: x_fromstr, y: y_fromstr }) } } let expected = Ok(Point { x: 1, y: 2 }); // Явный вызов assert_eq!(Point::from_str("(1,2)"), expected); // Неявные вызовы через parse assert_eq!("(1,2)".parse(), expected); assert_eq!("(1,2)".parse::<Point>(), expected); // Некорректная входная строка assert!(Point::from_str("(1 2)").is_err()); }
Связанные типы (Обязательные)
type Err
Связанный тип ошибки, который может быть возвращен при парсинге.
Обязательные методы
fn from_str(s: &str) -> Result<Self, Self::Err>
Парсит строку s, чтобы вернуть значение этого типа.
Если парсинг успешен, возвращает значение внутри Ok, в противном случае, когда строка имеет неправильный формат, возвращает ошибку, специфичную для внутренней части Err. Тип ошибки специфичен для реализации трейта.
Примеры
Базовое использование с i32 — типом, который реализует FromStr:
#![allow(unused)] fn main() { use std::str::FromStr; let s = "5"; let x = i32::from_str(s).unwrap(); assert_eq!(5, x); }
Совместимость с dyn (динамической диспетчеризацией)
Этот трейт не совместим с dyn.
В более старых версиях Rust совместимость с dyn называлась "объектной безопасностью" (object safety), поэтому этот трейт не является объектно-безопасным.
Реализации (Implementors)
| Тип | Назначение (реализации FromStr) |
|---|---|
IpAddr | Парсинг IP-адреса (IPv4 или IPv6) |
SocketAddr | Парсинг сетевого адреса (IP + порт) |
bool | Парсинг логического значения ("true"/"false") |
char | Парсинг одного Unicode символа |
f16 | Парсинг 16-битного числа с плавающей запятой |
f32 | Парсинг 32-битного числа с плавающей запятой |
f64 | Парсинг 64-битного числа с плавающей запятой |
i8 | Парсинг 8-битного целого числа со знаком |
i16 | Парсинг 16-битного целого числа со знаком |
i32 | Парсинг 32-битного целого числа со знаком |
i64 | Парсинг 64-битного целого числа со знаком |
i128 | Парсинг 128-битного целого числа со знаком |
isize | Парсинг целого числа со знаком размером с указатель |
u8 | Парсинг 8-битного целого числа без знака |
u16 | Парсинг 16-битного целого числа без знака |
u32 | Парсинг 32-битного целого числа без знака |
u64 | Парсинг 64-битного целого числа без знака |
u128 | Парсинг 128-битного целого числа без знака |
usize | Парсинг целого числа без знака размером с указатель |
ByteString | Парсинг байтовой строки |
CString | Парсинг строки, оканчивающейся нулем, для взаимодействия с C |
OsString | Парсинг строки, специфичной для платформы |
Ipv4Addr | Парсинг IPv4 адреса |
Ipv6Addr | Парсинг IPv6 адреса |
SocketAddrV4 | Парсинг IPv4 сетевого адреса (IPv4 + порт) |
SocketAddrV6 | Парсинг IPv6 сетевого адреса (IPv6 + порт) |
NonZero<i8> | Парсинг гарантированно ненулевого i8 |
NonZero<i16> | Парсинг гарантированно ненулевого i16 |
NonZero<i32> | Парсинг гарантированно ненулевого i32 |
NonZero<i64> | Парсинг гарантированно ненулевого i64 |
NonZero<i128> | Парсинг гарантированно ненулевого i128 |
NonZero<isize> | Парсинг гарантированно ненулевого isize |
NonZero<u8> | Парсинг гарантированно ненулевого u8 |
NonZero<u16> | Парсинг гарантированно ненулевого u16 |
NonZero<u32> | Парсинг гарантированно ненулевого u32 |
NonZero<u64> | Парсинг гарантированно ненулевого u64 |
NonZero<u128> | Парсинг гарантированно ненулевого u128 |
NonZero<usize> | Парсинг гарантированно ненулевого usize |
PathBuf | Парсинг пути в файловой системе |
String | Парсинг строки (фактически создание String из &str) |
Literal | Парсинг токена литерала (в контексте макросов/proc-macro) |
TokenStream | Парсинг потока токенов (в контексте макросов/proc-macro) |