07. Често срещани trait-ове

07. Често срещани trait-ове

07. Често срещани trait-ове

27 октомври 2017

Административни неща

Преговор

Гласуване

Как да наричаме оператора ::?

Домашното

Demo

Често използвани trait-ове

Често използвани trait-ове

Списък

Clone

trait Clone {
    fn clone(&self) -> Self;

    fn clone_from(&mut self, source: &Self) { ... }
}

Copy

trait Copy: Clone { }

Можем да имплементираме Copy само ако:

Drop

pub trait Drop {
    fn drop(&mut self);
}

Default

trait Default {
    fn default() -> Self;
}

Hash

Display & Debug

struct MagicTrick {
    description: String,
    secrets: Vec<String>,
    skills: Vec<String>
}

let trick = MagicTrick {
    description: String::from("Изчезваща монета"),
    secrets: vec![String::from("Монетата се прибира в ръкава")],
    skills: vec![String::from("Бързи ръце"), String::from("Заблуда")]
};

println!("{}", trick);
println!("===");
println!("{:?}", trick);

Display & Debug

Ще очакваме следния изход след като имплементираме Dispay и Debug за MagicTrick

Магически трик "Изчезваща монета"
===
Трик
  Описание: "Изчезваща монета"
  Тайни: ["Монетата се прибира в ръкава"]
  Умения: ["Бързи ръце", "Заблуда"] 

Display

Display

use std::fmt::{self, Display, Formatter};

impl Display for MagicTrick {
    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
        write!(f, "Магически трик {:?}", self.description)
    }
}

Display

Нека да разбием примера и да видим какво oзначават новите неща

Макрос write

write!(f, "Магически трик {:?}", self.description)

Result

enum Result<T, E> {
    Ok(T),
    Err(E),
}

Display

let trick = MagicTrick {
    description: String::from("Изчезваща монета"),
    secrets: vec![String::from("Монетата се прибира в ръкава")],
    skills: vec![String::from("Бързи ръце"), String::from("Заблуда")]
}

println!("{}", trick);

Debug

Debug

use std::fmt::{self, Debug, Formatter};

impl Debug for MagicTrick {
    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
        write! {
            f,
            r#"
            Трик
              Описание: {:?}
              Тайни {:?}
              Умения {:?}
            "#,
            self.description,
            self.secrets,
            self.skills
        }
    }
}

Display & Debug

let trick = MagicTrick {
    description: String::from("Изчезваща монета"),
    secrets: vec![String::from("Монетата се прибира в ръкава")],
    skills: vec![String::from("Бързи ръце"), String::from("Заблуда")]
};

println!("{}", trick);
println!("===");
println!("{:?}", trick);

Предефиниране на оператори

Операторите се дефинират с trait-ове

Видяхме trait-а Add, с който дефинираме оператора +

trait Add<RHS = Self> {
    type Output;

    fn add(self, rhs: RHS) -> Self::Output;
}

Предефиниране на оператори

Примери

Предефиниране на оператори

Demo

Предефиниране на оператори

Eq

trait PartialEq<Rhs = Self> where Rhs: ?Sized {
    fn eq(&self, other: &Rhs) -> bool;

    fn ne(&self, other: &Rhs) -> bool { ... }
}

Предефиниране на оператори

Eq

trait Eq: PartialEq<Self> { }

Предефиниране на оператори

Ord

trait PartialOrd<Rhs = Self>: PartialEq<Rhs> where Rhs: ?Sized {
    fn partial_cmp(&self, other: &Rhs) -> Option<Ordering>;

    fn lt(&self, other: &Rhs) -> bool { ... }
    fn le(&self, other: &Rhs) -> bool { ... }
    fn gt(&self, other: &Rhs) -> bool { ... }
    fn ge(&self, other: &Rhs) -> bool { ... }
}

enum Ordering {
    Less,
    Equal,
    Greater,
}

Предефиниране на оператори

Ord

Дефинира операторите < <= > >=

PartialOrd дефинира частична наредба

assert_eq!(f64::NAN < 0., false);
assert_eq!(f64::NAN >= 0., false);

Предефиниране на оператори

Ord

trait Ord: Eq + PartialOrd<Self> {
    fn cmp(&self, other: &Self) -> Ordering;

    fn max(self, other: Self) -> Self { ... }
    fn min(self, other: Self) -> Self { ... }
}

Дефинира тотална наредба

Въпроси