Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

From і Into

Трейт-и From і Into невід’ємно пов’язані, і це фактично є частиною його реалізації. Якщо ви можете перетворити тип A з типу B, тоді легко повірити, що ми повинні мати змогу перетворити тип B у тип A.

From

Трейт From дозволяє типу визначити, як створити самого себе з іншого типу, тим самим надаючи дуже простий механізм для перетворення між кількома типами. У стандартній бібліотеці є численні реалізації цього трейт-а для перетворення примітивних і поширених типів.

Наприклад, ми можемо легко перетворити str у String

#![allow(unused)]
fn main() {
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. Він визначає, як перетворити один тип в інший тип.

Виклик 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;
    // Try removing the type annotation
    let num: Number = int.into();
    println!("My number is {:?}", num);
}

From and Into are interchangeable

From і Into призначені бути взаємодоповнювальними. Нам не потрібно надавати реалізацію для обох трейтів. Якщо ви реалізували трейт From для вашого типу, Into викличе його за потреби. Зауважте, однак, що зворотне не є істинним: реалізація Into для вашого типу не надасть йому автоматично реалізацію From.

use std::convert::From;

#[derive(Debug)]
struct Number {
    value: i32,
}

// Define `From`
impl From<i32> for Number {
    fn from(item: i32) -> Self {
        Number { value: item }
    }
}

fn main() {
    let int = 5;
    // use `Into`
    let num: Number = int.into();
    println!("My number is {:?}", num);
}