学习笔记
Git
  • C#
  • F#
  • AspNetCore
  • EF Core
  • WPF
  • Tauri
  • IoTDB
  • Redis
  • Docker
  • Kubernetes
  • RabbitMQ
  • 日志

    • NLog的配置文件
Linux
  • 基础环境之WSL
基础设施
  • Vue

    • Vue基础
VS Code的插件与玩法
Rust
Python
  • Maven
  • Spring Boot
实际项目
我的博客
Git
  • C#
  • F#
  • AspNetCore
  • EF Core
  • WPF
  • Tauri
  • IoTDB
  • Redis
  • Docker
  • Kubernetes
  • RabbitMQ
  • 日志

    • NLog的配置文件
Linux
  • 基础环境之WSL
基础设施
  • Vue

    • Vue基础
VS Code的插件与玩法
Rust
Python
  • Maven
  • Spring Boot
实际项目
我的博客
  • Rust中的变量
  • 数据类型
  • 函数
  • 控制流
  • 所有权
  • 结构体

结构体和我们在“元组类型”部分论过的元组类似,它们都包含多个相关的值。和元组一样,结构体的每一部分可以是不同类型。但不同于元组,结构体需要命名各部分数据以便能清楚的表明其值的意义。由于有了这些名字,结构体比元组更灵活:不需要依赖顺序来指定或访问实例中的值。

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

结构体赋值

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

简化赋值

Rust在给结构体赋值时可以简化,行为与JavaScript类似

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

当参数与结构体的字段同名时,可以简化写法

从其他实例创建实例

fn main() {
    // --snip--

    let user2 = User {
        email: String::from("[email protected]"),
        ..user1
    };
}

当需要从一个实例创建另一个实例时,除了常规的每个字段都进行赋值,还可以选择这种结构体更新语法,近指定需要变化的字段,然后解构原来的结构体(与JavaScript中的解构赋值类似)

特殊的结构体

元组结构体

元组结构体有着结构体名称提供的含义,但没有具体的字段名,只有字段的类型。

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

如果是元组,那么同样的三个整数是没有区分的,但是元组结构体能够表明这里是RGB颜色,还是XYZ坐标

类单元结构体

一个没有任何字段的结构体,它们被称为 类单元结构体(unit-like structs)因为它们类似于 ()

类单元结构体常常在你想要在某个类型上实现 trait 但不需要在类型中存储数据的时候发挥作用。

结构体方法

方法与函数类似,它们使用 fn 关键字和名称声明,可以拥有参数和返回值,同时包含在某处调用该方法时会执行的代码。不过方法与函数是不同的,因为它们在结构体的上下文中被定义(或者是枚举或 trait 对象的上下文),并且它们第一个参数总是 self,它代表调用该方法的结构体实例。

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

// impl 是 implementation 的缩写
// 这个 impl 块中的所有内容都将与 Rectangle 类型相关联
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()
    );
}

关联函数

所有在 impl 块中定义的函数被称为 关联函数(associated functions),因为它们与 impl 后面命名的类型相关。我们可以定义不以 self 为第一参数的关联函数(因此不是方法),因为它们并不作用于一个结构体的实例。我们已经使用了一个这样的函数:在 String 类型上定义的 String::from 函数。

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

impl Rectangle {
    fn square(size: u32) -> Self {
        Self {
            width: size,
            height: size,
        }
    }
}
// 调用关联函数,使用结构体名和 :: 语法
let sq = Rectangle::square(3)

不是方法的关联函数经常被用作返回一个结构体新实例的构造函数。这些函数的名称通常为 new ,但 new 并不是一个关键字

Last Updated:
Contributors: 吴俊城
Prev
所有权