foxlog
5/12/2019 - 3:36 PM

rust编程之道笔记

rust编程之道笔记

here is about the dao of rust

trait实现加法抽象

数学运算加法

trait Add<RHS, Output> {
  fn add(self, rhs: RHS) -> Output;
}

impl Add<i32, i32> for i32 {
  fn add(self, rhs: i32) -> i32 {
    self + rhs
  }
}

impl Add<u32, i32> for u32 {
  fn add(self, rhs: u32) -> i32 {
    (self + rhs) as i32
  }
}

fn main() {
  let (a, b, c, d) = (1i32, 2i32, 3u32, 4u32);
  let x: i32 = a.add(b);
  let y: i32 = c.add(d);
  assert_eq!(x, 3i32);
  assert_eq!(y, 7i32);
}

标准库中的String类型实现Add trait

pub trait Add<Rhs=Self> {
    /// The resulting type after applying the `+` operator.
    #[stable(feature = "rust1", since = "1.0.0")]
    type Output;

    /// Performs the `+` operation.
    #[must_use]
    #[stable(feature = "rust1", since = "1.0.0")]
    fn add(self, rhs: Rhs) -> Self::Output;
}

#[stable(feature = "rust1", since = "1.0.0")]
impl Add<&str> for String {
    type Output = String;

    #[inline]
    fn add(mut self, other: &str) -> String {
        self.push_str(other);
        self
    }
}
fn main() {
  let a = "hello";
  let b = " world";
  let c = a.to_string() + b;
  println!("{:?}", c); // hello world
}

#question 如何识别加号 "+" ? 哪里可以看到具体实现?

trait一般用法

learning rust: impl and trait

impl without trait

struct Player, impl Player , same name without 'for' keyword

struct Player {
    first_name: String,
    last_name: String,
}

impl Player {
    fn full_name(&self) -> String {
        format!("{} {}", self.first_name, self.last_name)
    }
}

fn main() {
    let player_1 = Player {
        first_name: "Rafael".to_string(),
        last_name: "Nadal".to_string(),
    };

    println!("Player 01: {}", player_1.full_name());
}

// ⭐️ Implementation must appear in the same crate as the self type

//  And also in Rust, new traits can be implemented for existing types even for types like i8, f64 and etc.
// Same way existing traits can be implemented for new types you are creating.
// But we can not implement existing traits into existing types.

Impls & traits, without default methods

trait only has signature for function, no detail implementation

struct Player {
    first_name: String,
    last_name: String,
}

trait FullName {
    fn full_name(&self) -> String;
}

impl FullName for Player {
    fn full_name(&self) -> String {
        format!("{} {}", self.first_name, self.last_name)
    }
}

fn main() {
    let player_2 = Player {
        first_name: "Roger".to_string(),
        last_name: "Federer".to_string(),
    };

    println!("Player 02: {}", player_2.full_name());
}

//  Other than functions, traits can contain constants and types.

Impls, traits & default methods

struct Player {
    first_name: String,
    last_name: String,
}

trait FullName {
    fn full_name(&self) -> String;
    
    //default method for trait 
    fn say_hello(&self) {
        println!("hello world");
    }
}

impl FullName for Player {
    fn full_name(&self) -> String {
        format!("{} {}", self.first_name, self.last_name)
    }
}

fn main() {
    let player_2 = Player {
        first_name: "Roger".to_string(),
        last_name: "Federer".to_string(),
    };

    println!("Player 02: {}", player_2.full_name());
    player_2.say_hello();
}

trait 继承

pub trait B: A {} This is not really inheritance. It’s more like “things that implement B also need to implement A”. 并不是真正的继承, 仅仅是一个声明, 意思是实现了B的也需要实现A

pub trait Animal {
    fn howl(&self) { println!("ao ao"); }
}
pub trait Tiger: Animal {
    fn find_food(&self) { println!("find food"); }
}

impl<'a> Animal for &'a str {}
impl<'a> Tiger for &'a str {}

fn main(){
    "hello".howl();
    "hello".find_food(); //find food
}

Rust有两个Edition其实并不是一个bad way.

Rust: A Language for the Next 40 Years - Carol Nichols

仅是在High level层面

可以交叉使用