Rust 学习笔记

https://doc.rust-lang.org/std/keyword.ref.html
https://www.bilibili.com/video/BV19b4y1o7Lt
https://tyrchen.github.io/rust-training/rust-training-all-in-one-cn.html

struct, enum

struct 仅仅用来定义一组数据,enum 枚举

struct Human {
    name: String,
    gender: Gender,
}
enum Gender {
    Unknown = 0,
    Female = 1,
    Male = 2,
}

associated functions and methods

impl Human {
    fn new() -> Self { Human{name: "hangj".into(), gender: Gender.Male, } }
    fn test(_i: i32, _j: i32){}
}

这种就是 associated function,它的调用方式是 Human::new() Human::test(1, 2)

impl Human {
    fn sleep(&self){}
    fn eat(&mut self, _food: String){}
}

这种第一个参数是 &self 的函数就是 method,调用方式是通过 struct 的实例(instance) 去调用

fn main() {
    let human = Human::new();
    human.sleep();
}

也可以这样写 Human::sleep(&human) , 其实本质上,调用方式跟 associated function 并无区别, 只不过是语言层面提供的语法糖(syntax sugar)
&self&mut self 也是个语法糖,其实就是 self: &Humanself: &mut Human

Human::sleep(&human) 这种写法这么麻烦,什么时候才有必要这么写呢?
当它需要显式调用某个 trait 的同名函数时。

trait 是啥

trait 就类似 C++ 中的纯虚函数,定义一组接口,是一种约定

trait Animal{
    fn noise(&self)-> &'static str;
}

struct Sheep{}
struct Cow{}
struct Human{}


impl Animal for Sheep {
    fn noise(&self) -> &'static str {"mieeeeeee"}
}
impl Animal for Cow {
    fn noise(&self) -> &'static str {"mooooooo"}
}
impl Animal for Human {
    fn noise(&self) -> &'static str {"66666"}
}

impl Human{
    fn noise(&self)-> &'static str{
        "hahahah"
    }
}

fn main() {
    let cow = Cow{};
    let sheep = Sheep{};
    let human = Human{};

    println!("{}", cow.noise());
    println!("{}", sheep.noise());
    println!("{}", human.noise());
    println!("{}", Human::noise(&human)); // 与 human.noise() 等效
    println!("{}", Animal::noise(&human)); // 显式调用 Animal 的 noise
}

trait 参数

fn call_noise(ins: &impl Animal) {
    println!("{}", ins.noise());
}

任何实现了 Animal 的 struct 的 instance 都可以作这个函数的参数

如果有多个 trait,则需要用 + 将 trait 连接起来

fn foo(v: impl Trait1 + Trait2){}

trait 作返回值

fn foo() -> impl Animal {
    Human{}
}

generics 范型

struct Pos<T> {
    x: T,
    y: T,
}

fn get_type_name<T>(_v: &T) -> &'static str {
    std::any::type_name::<T>()
}

fn main() {
    println!("{}", get_type_name(&0));
    println!("{}", get_type_name(&("hello".to_string())));
    println!("{}", get_type_name(&Pos{x:1, y:2}));
}

trait + generic

上文中的 call_noise 可以定义如下

fn call_noise<T: Animal>(ins: &T){
    println!("{}", ins.noise());
}

或者

fn call_noise<T>(ins: &T)
where T: Animal,
{
    println!("{}", ins.noise());
}

如果有多个 trait,则需要将多个 trait 用 + 连接

struct P<T: Trait1 + Trait2>{ }
fn foo<T: Trait1 + Trait2>(){}

attributes

https://cloud.tencent.com/developer/article/1594094
https://doc.rust-lang.org/reference/attributes.html

posted on 2022-05-21 15:03  明天有风吹  阅读(58)  评论(0编辑  收藏  举报

导航

+V atob('d2h5X251bGw=')

请备注:from博客园