From
и Into
Трейты From
и Into
тесно связаны, и это на самом деле часть их реализации. Если вы можете преобразовать тип A из типа B, то, логично, полагаться на то, что мы сможем преобразовать тип B в тип A.
From
Трейт From
позволяет типу определить, как создавать себя из другого типа, тем самым обеспечивая очень простой механизм преобразования между несколькими типами. В стандартной библиотеке имеется множество реализаций этого трейта для преобразования примитивных и распространенных типов.
Например, мы можем легко преобразовать str
в String
let my_str = "hello";
let my_string = String::from(my_str);
Мы можем сделать то же самое для определения преобразования для нашего собственного типа.
use std::convert::From;
#[derive(Debug)]
struct Number {
value: i32,
}
impl From<i32> for Number {
fn from(item: i32) -> Self {
Number { value: item }
}
}
fn main() {
let num = Number::from(30);
println!("My number is {:?}", num);
}
Into
Трейт Into
просто обратное отображение для трейта From
. То есть, если вы реализовали трейт From
для своего типа, Into
вызовет его при необходимости.
При использовании трейта Into
обычно потребуется указать тип, в который нужно преобразовать, так как компилятор в большинстве случаев не может определить это самостоятельно. Однако это небольшая цена за то, что мы получаем эту функциональность бесплатно.
use std::convert::Into;
#[derive(Debug)]
struct Number {
value: i32,
}
impl Into<Number> for i32 {
fn into(self) -> Number {
Number { value: self }
}
}
fn main() {
let int = 5;
// Попробуйте удалить аннотацию типа
let num: Number = int.into();
println!("My number is {:?}", num);
}