parse?
Ответы вида: ну, парсит строку в указанный тип - не принимаются
Мне интересно, каким образом это происходит и можно ли реализовать что-то подобное собственноручно?
До меня просто немного не доходит, каким образом Rust проверяет, какой тип был передан, чтобы парсить именно в него
а что принимаете? российские рубли принимаете?
Так исходный код же открыт
Давайте внимательно посмотрим на сигнатуру. Это метод на str, который берёт self (str, то есть некое "123"), а отдаёт F - нечто(генерик-параметр), что реализует FromStr. То есть "парсится из строки" у вас буде только то, что реализовало FromStr. Поэтому и работает "123".parse::<u64>(), потому что есть impl FromStr for u64. Считайте, этот метод просто шорткат для let my_var = <u64 as FromStr>::from_str("123") , что весьма длинно, а вот let my_var = "123".parse::<u64>() - покороче и красивее, хоть и скрывает настоящий вызов внутри (благо посмотреть его буквально ctrl + click)
Можно ли для своего? Да. Достаточно сделать импл своего типа для FromStr. struct MyStruct(u64); impl core::str::FromStr for MyStruct { type Err = std::num::ParseIntError; fn from_str(s: &str) -> Result<Self, Self::Err> { Ok(MyStruct(s.parse::<u64>()?)) } } #[test] fn test_parse() { let left = "123".parse::<MyStruct>().unwrap(); let right = "123".parse::<u64>().unwrap(); assert_eq!(left.0, right); }
Хорошо, так, с этим, вроде как, понял, однако... Это вообще легально? В плане, я так понимаю, что вызывается сам метод именно трейта, а не переданного типа, получается... Что-то запутался. Почему вызывается берётся трейт, а не его реализация?🤔 Возможно, я плохо изучил трейты, тут прям не спорю
parse - метод str, требующий генерик-параметром и вызывающий внутри FromStr вам ничего не мешает сделать MyStruct с трейтом FromMyStruct и методом parse. то есть вы можете это повторить.
Ого👀 Спасибо огромное Всё больше и больше начинаю любить Rust :D
Хорошо, понял, спасибо огромное, попробую поэкспериментировать :D
Обсуждают сегодня