Rust-Lang Book Ch. 5 Structs

Struct的声明和实例化

声明

struct User {
    username: String,
    email: String,
    sign_in_count: u64,
    active: bool,
}

  

实例化,注意Rust要求每个成员变量的生命周期至少和Struct变量本身一样长

    let user1 = User {
        email: String::from("someone@example.com"),
        username: String::from("someusername123"),
        active: true,
        sign_in_count: 1,
    };

 

在实例化时,如果本地变量和成员变量恰好名字相同,就可以省去成员变量:

fn build_user(email: String, username: String) -> User {
    User {
        email,
        username,
        active: true,
        sign_in_count: 1,
    }
}

  

可以使用旧Struct变量的成员变量来创建一个新的Struct:

 let user2 = User {
        email: String::from("another@example.com"),
        username: String::from("anotherusername567"),
        ..user1
    };

  

Tuple Structs

Tuple Struct的意义在于给当前tuple组合一个特定的类型名称,使之和其他的tuple不同,例如:

    struct Color(i32, i32, i32);
    struct Point(i32, i32, i32);

    let black = Color(0, 0, 0);
    let origin = Point(0, 0, 0);

  

Unix-Like Structs

在Rust中,可以定义没有任何成员变量的Struct。因为他们类似(),所以被称为Unit-like structs。这些Structs有助于各种不需要实际数据但是需要依托具体struct的traits的实现。

 

Traits

struct Rectangle {
    width: u32,
    height: u32,
}

fn main() {
    let rect1 = Rectangle {
        width: 30,
        height: 50,
    };

    println!("rect1 is {}", rect1);
}

  

println!是一个宏,当它看到{}的时候,就去找对应类型的Display方法,{:?},则取该类型所实现的std::fmt::Debug方法。

为了给Struct Rectangle实现std::fmt::Debug接口,只需要加上[derive(Debug)]这个注解,Rust就能自动地产生最简单的Debug方法。

#[derive(Debug)]
struct Rectangle {
    width: u32,
    height: u32,
}

fn main() {
    let rect1 = Rectangle {
        width: 30,
        height: 50,
    };

    println!("rect1 is {:#?}", rect1);//与{:?}相比,{:#?}是pretty print style
}
cargo run
   Compiling structs v0.1.0 (file:///projects/structs)
    Finished dev [unoptimized + debuginfo] target(s) in 0.48s
     Running `target/debug/structs`
rect1 is Rectangle { 
width: 30,
height: 50,
}

  

Rust本身已经为我们用derive注解提供了很多默认的行为。

 

Struct Methods

Method一般第一个参数永远是&self

impl Rectangle {
    fn area(&self) -> u32 {
        self.width * self.height
    }

    fn can_hold(&self, other: &Rectangle) -> bool {
        self.width > other.width && self.height > other.height
    }
}//当然可以用多个impl Rectangle块

  

在调用时,只需简单使用类似v1.can_hold(&v2),而不需要调用(&v1).can_hold(&v2)或者(&mut v1).change_sth(&v2)。这是因为Rust中有automatic referencing和dereferencing机制。在Rust编程时,无需使用pointer->sth()或者(*pointer).sth(),可以理解为,编译器会确定当前method调用是对self对应的变量做read(&self),mutating(&mut self)还是consuming(self),自动地帮代码从obj.sth()变成(&obj).sth()或者(&mut obj).sth()或者obj.sth()

 

Associated functions

可以定义不把self作为参数的函数,这些函数被称为相关函数(Associated functions),这些函数不是成员方法,例如String::from就不是方法。Associated function一般被用作constructors。

 

上一篇:POJ-2559Largest Rectangle in a Histogram(单调栈)


下一篇:C# 无边框窗体开发窗体伸缩功能(windows消息)