【Rust 中级教程】 02 结构体与泛型

简介: 【Rust 中级教程】 02 结构体与泛型

0x00 开篇


上一篇文章简单介绍了泛型,本篇文章将继续介绍泛型的相关概念——泛型结构体。在介绍泛型结构体前,还需要先介绍下如何在结构体中定义方法,以及泛型方法。本篇文章也算作是对结构体章节的一个补充。


0x01 方法与函数


方法表示某个类型实例的行为,方法与函数的定义大同小异。在前面文章中,不知道你有没有发现,函数和方法这两个词都出现过。在结构体中,方法必须定义在 impl 块中。方法要求第一个参数必须是 &self 或者是 &mut self,这也是与函数的唯一区别。在方法中,使用 &self 读取实例中的数据,使用 &mut self 可以读写实例中的数据。


‍0x02 在结构体中定义方法


先上代码,后解释。

struct Person {
    // 名字
    name: String,
    // 年龄
    age: u8,
}
impl Person {
    // 方法
    fn get_age(&self) -> u8 {
        return self.age;
    }
    fn set_age(&mut self, age: u8) {
        self.age = age;
    }
    fn get_name(&self) -> &str {
        return self.name.as_str();
    }
    fn set_name(&mut self, name: &str) {
        self.name = name.to_string();
    }
    //关联函数
    fn to_string(person: Person) -> String {
        return format!("Person {{ name: {}, age: {} }}", person.get_name(), person.get_age());
    }
}
fn main() {
    let mut person = Person {
        name: String::from("test"),
        age: 8,
    };
    println!("修改前:name: {}, age: {}", person.get_name(), person.get_age());
    person.set_name("张三");
    person.set_age(18);
    println!("修改后:name: {}, age: {}", person.get_name(), person.get_age());
    // 通过关联函数输出
    println!("{}", Person::to_string(person))
    // 输出结果:
    // 修改前:name: test, age: 8
    // 修改后:name: 张三, age: 18
    // Person { name: 张三, age: 18 }
}

首先我们定义一个结构体 _Person_,我们通过 impl 为其添加方法。其中,所有方法的第一个参数都是 &self 或者是 &mut self。在 impl 块中,我们定义了 get_age,set_age,get_name,set_name 四个方法。再看 main 函数块内,我们可以通过“实例名.方法名”的语法来调用方法。调用方法时,不需要传递 self 参数,self 参数将由编译器自动传递。另外,我们还在结构体内定义了一个关联函数 to_string 来打印内容。我们通过 “结构体名::函数名”的语法来调用结构体内的关联函数。


0x03 泛型结构体


结构体也可以是泛型的,换句话讲,我们可以使用泛型写一个通用的结构体模板。前面介绍的 Vec 向量就是一个泛型结构体类型,这种结构体可以插入任何数据类型,我们下面以自定义一个“队列”来介绍泛型结构体,先上代码。

/// 定义一个队列
struct Queue<T> {
    // 通过向量存储数据
    data: Vec<T>,
    // 队列的长度
    size: u32,
}
///  定义队列的方法
impl<T> Queue<T> {
    /// 创建一个队列
    /// 这是一个关联函数
    pub fn new() -> Queue<T> {
        Queue {
            data: vec![],
            size: 0,
        }
    }
    /// 向队列中插入一个值
    /// 这是一个方法
    pub fn offer(&mut self, value: T) {
        self.data.push(value);
        self.size += 1;
    }
    /// 弹出队列的最顶部的元素
    /// 这是一个方法
    pub fn poll(&mut self) {
        if self.size > 0 {
            self.data.remove(0);
            self.size -= 1;
        }
    }
}
fn main() {
    let mut queue: Queue<i32> = Queue::new();
    queue.offer(4);
    queue.offer(7);
    queue.offer(10);
    println!("队列的长度:{}", queue.size);
    queue.poll();
    queue.poll();
    queue.poll();
    queue.offer(10);
    println!("队列的长度:{}", queue.size);
    // 输出结果:
    // 队列的长度:3
    // 队列的长度:1
}

首先定义一个队列结构体 Queue,定义结构体时,需要在结构体名称后面加上泛型的标签。我们借助向量来存储数据,再额外维护一个队列的长度 size 变量,简单的队列就定义完成。接着定义队列的方法,这里与普通的结构体方法略有不同,我们定义泛型结构体时,需要在 impl 后面加上泛型的标签,然后再跟结构体的名称。在impl 块中,我们分别实现了创建一个队列的关联函数(new)和数据入队(offer),数据出队两个方法(poll)。


0x04 泛型方法


定义:带有泛型类型的参数或者是返回值的方法叫做泛型方法。上面代码中的 offer 方法就是一个泛型方法。泛型方法与泛型函数类似,我就不做介绍了。


0x05 小结


通过两篇文章,介绍了泛型的概念与泛型相关的一些数据类型——泛型与向量,泛型函数,泛型枚举,泛型结构体, 泛型方法等。有关泛型的相关知识基本已经写完了,但是结构体还没有。结构体是 Rust 中很重要的数据类型,它也是 Rust 面向对象的特征中最重要的组成部分。

相关文章
|
4月前
|
Rust 编译器
Rust 泛型
Rust 泛型
32 1
|
3月前
|
存储 Rust 程序员
【一起学Rust | 基础篇 | rust新特性】Rust 1.65.0——泛型关联类型、let-else语句
【一起学Rust | 基础篇 | rust新特性】Rust 1.65.0——泛型关联类型、let-else语句
52 0
|
24天前
|
Rust 安全 算法
【深入探索Rust:结构体、枚举与模式匹配】A Deep Dive into Rust: Structs, Enums, and Pattern Matching
【深入探索Rust:结构体、枚举与模式匹配】A Deep Dive into Rust: Structs, Enums, and Pattern Matching
43 0
【深入探索Rust:结构体、枚举与模式匹配】A Deep Dive into Rust: Structs, Enums, and Pattern Matching
|
1月前
|
存储 Rust 开发者
【Rust】——结构体struct
【Rust】——结构体struct
27 0
|
3月前
|
存储 Rust 算法
Rust 数据类型 之 结构体(Struct)
Rust 数据类型 之 结构体(Struct)
60 0
|
3月前
|
存储 Rust 安全
Rust 笔记:Rust 语言中的 结构体 与面向对象编程的实现
Rust 笔记:Rust 语言中的 结构体 与面向对象编程的实现
78 0
|
4月前
|
Rust 编译器
rust 泛型和特征(三)
rust 泛型和特征
50 0
|
4月前
|
Rust 编译器
rust 泛型和特征(二)
rust 泛型和特征
29 0
|
4月前
|
Rust
rust 泛型和特征(一)
rust 泛型和特征
46 0
|
4月前
|
存储 Rust C++
Rust 语言中的结构体
Rust 语言中的结构体