Skip to content
Published at:

Using Structs to Structure Related Data

内容:

  • 元组和结构体
  • 方法
  • 关联函数

定义并实例化结构体

结构体(structs):

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

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

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

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

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

// 同名:可以简化
fn build_user1(email: String, username: String) -> User {
    User {
        email,
        username,
        active: true,
        sign_in_count: 1,
    }
}

元组结构体(tuple structs):

rust
fn main() {
    // 元组结构体
    struct Color(i32, i32, i32);
    struct Point(i32, i32, i32);

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

    let r = black.0;
    let g = black.1;
    let b = black.2;
}

类单元结构体(unit-like structs):

(),即unit类型,

你想要某个类型实现trait,但不需要在类型中存储数据的时候发挥作用,

一个使用结构体的示例程序

示例:

rust
fn main() {
    let width1 = 30;
    let height1 = 50;
    println!(
        "The area of the rectangle is {} square pixels.",
        area(width1, height1)
  	);
}

fn area(width: u32, height: u32) -> u32 {
    width * height
}

元组重构:

rust
fn main() {
    let rect1 = (30, 50);
    println!(
        "The area of the rectangle is {} square pixels.",
        area(rect1)
  	);
}

fn area(dimensions: (u32, u32)) -> u32 {
    dimensions.0 * dimensions.1
}

结构体重构:

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

fn main() {
    let rect1 = Rectangle { width: 30, height: 50 };
    println!(
        "The area of the rectangle is {} square pixels.",
        area(&rect1)
  	);
}

fn area(rectangle: &Rectangle) -> u32 {
    rectangle.width * rectangle.height
}

通过派生Trait增加实用功能:

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

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

    println!("rect1 is  {:#?}", rect1);
}

方法语句:

方法定义:

方法(method)与函数(function):

  • 相同点:有fn关键字,有参数,有返回值,有被调用的会执行的代码,
  • 不同点:方法定义在结构体上下文中(或是枚举,或是trait的上下文中), 并且方法的第一个参数总是self
rust
#[derive(Debug)]
struct Rectangle {
    width: u32,
    height: u32,
}
impl Rectangle {
    fn area(&self) -> u32 {
        self.width * self.height
    }
}
fn main() {
    let rect1 = Rectangle { width: 30, height: 50 };
    println!(
        "The area of the rectangle is {} square pixels.",
        rect1.area()
  	);
}

所有权与self:

第一个参数self,&self&mut self.

C/C++中的指针运算符号->:

Rust有自动引用解引用的功能. 原理:当调用方法时,Rust会为object添加&,&mut*与方法签名匹配.

带更多参数的方法:

rust
#[derive(Debug)]
struct Rectangle {
    width: u32,
    height: u32,
}
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
		}
}
fn main() {
    let rect1 = Rectangle { width: 30, height: 50 };
    println!(
        "The area of the rectangle is {} square pixels.",
        rect1.area()
  	);
}

关联函数:

定义:在impl块中定义不以self作为参数的函数,被称为关联函数associated functions. 与结构体关联,但仍然是函数而不是方法,比如String::from(). 在其它语言中被称为静态函数

rust
#[derive(Debug)]
struct Rectangle {
    width: u32,
    height: u32,
}
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 {
    fn square(size: u32) -> Rectangle {
        Rectangle { width: size, height: size }
    }
}
fn main() {
    let rect1 = Rectangle { width: 30, height: 50 };
    println!(
        "The area of the rectangle is {} square pixels.",
        rect1.area()
  	);
}

多个impl块:

rust
impl Rectangle {
    fn area(&self) -> u32 {
        self.width * self.height
    }
}
impl Rectangle {
    fn can_hold(&self, other: &Rectangle) -> bool {
        self.width > other.width && self.height > other.height
    }
}