Rust—结构体

结构体

一、基本概念

  • Rust 语言自身有的数据类型,虽说已经挺多,但是有时候并不能满足我们的需要,例如当我们需要一种能存储学生信息的数据类型时,Rust 自有的数据类型是不能做到的,因为一条学生信息记录既有数字又有文字。
  • 因此,Rust 像其他编程语言一样,允许开发者根据自己需要定义自定义数据类型,而结构体就是一种自定义数据类型。

1、定义方式

  • Rust 语言中的结构体,也是使用关键字 struct 来声明定义的。
  • 在我所学习过的编程语言中,支持以结构体来自定义数据类型的,目前只有 C/C++ 和 Rust,Python 与 Java 都没有。
  • Rust 中定义结构体的形式如下:
    struct 结构体名 {
    		数据1:数据类型1,
    		数据2:数据类型2,
    		...
    	}
    
  • 结构体中,每个数据名及其对应的数据类型组成一个字段,结构体中可以根据需要定义字段个数,理论上要多少就定义多少;但实际上,建议结构体中的字段不要超过 15 个,特别是包含不同数据类型的结构体;因为字段太多,结构体也会变得很占空间,对程序的空间上的效率十个负担。

2、简单的结构体例子

  • 以学生信息为例举个简单的结构体例子,其代码如下:
    struct Student {
    		name:String,
    		age:u32,
    		grade:String,
    		state:bool
    }
    

二、结构体的使用

  • 结构体的使用,首先要将结构体实例化。

1、结构体实例化

  • 实例化,就是给结构体中的字段赋值;实例过程中结构体字段的顺序应当和声明的时候一样,如下示例:
    fn main() {
        let s1 = Student{
            name:String::from("张三"),
            age:23,
            grade:String::from("高三"),
            state:true
        };
        println!("学生{},年纪{},年级{},在学状态{}", s1.name, s1.age, s1.grade, s1.state);
    }
    struct Student {
        name:String,
        age:u32,
        grade:String,
        state:bool
    }
    // 输出:
    // 学生张三,年纪23,年级高三,在学状态true
    

2、结构体取值和改值

  • 由例子也可以看出,取结构体种某个字段的值的方式是:结构体名.字段名,这个和 C/C++ 语言一样。
  • 同理,修改结构体中某个字段的值,可以用:结构体名.字段名=新值 形式,如下示例:
    fn main() {
        let mut s1 = Student{
            name:String::from("张三"),
            age:23,
            grade:String::from("高三"),
            state:true
        };
        println!("学生{},年纪{},年级{},在学状态{}", s1.name, s1.age, s1.grade, s1.state);
        s1.grade = String::from("大二");
        println!("学生{},年纪{},年级{},在学状态{}", s1.name, s1.age, s1.grade, s1.state);
    }
    struct Student {
        name:String,
        age:u32,
        grade:String,
        state:bool
    }
    /*输出
    学生张三,年纪23,年级高三,在学状态true
    学生张三,年纪23,年级大二,在学状态true
    */
    

3、结构体做返回值

  • 结构体也可以作为函数的返回值来使用,如下示例:
    fn main() {
        let s2 = build_student(String::from("御承扬"), 21, String::from("大三"), true);
        println!("学生{},年纪{},年级{},在学状态{}", s2.name, s2.age, s2.grade, s2.state);
    }
    
    struct Student {
        name: String,
        age: u32,
        grade: String,
        state: bool,
    }
    
    fn build_student(_name: String, _age: u32, _grade: String, _state: bool) -> Student {
        Student {
            name: _name,
            age: _age,
            grade: _grade,
            state: _state,
        }
    }
    // 输出
    // 学生御承扬,年纪21,年级大三,在学状态true
    

3.1、变量与字段同名时的字段初始化简写语法

  • 当参数名与字段名相同时,可以使用字段初始化简写语法,如下例子:
    fn build_student2(name:String, age:u32, grade:String, state:bool) -> Student {
        Student{
            name,
            age,
            grade,
            state
        }
    }
    

4、元组结构体

  • 元组结构体,一种和元组类似的结构体。
  • 元组结构体有着结构体名称提供的含义,但没有具体的字段名,只有字段的类型。
  • 示例:
    struct Color(i32, i32, i32);
    struct Point(i32, i32, i32);
    let black = Color(0, 0, 0);
    let origin = Point(0, 0, 0);
    

5、结构体使用案例

  • 首先使用非结构体模式,定义一个简单的函数:求面积,如下:
    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
    }
    

5.1、使用元组重构

  • 接着用元组对上述求面积的函数进行重构:
    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
    }
    

5.2、使用结构体重构

  • 接着受用结构体再次对函数进行重构:
    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
    }
    
  • 以上三个例子的输出都是一样的:
    The area of the rectangle is 1500 square pixels.
    

6、使用 println!("{:?}") 输出结构体内容

  • 如果直接使用之前的 println!("{}") 来输出结构体的内容,则会报错如下:
    error[E0277]: the trait bound `Rectangle: std::fmt::Display` is not satisfied
    
  • 进行适当修改,使用 println!("{:?}") 则可以输出结构体的内容,如下示例:
    #[derive(Debug)]
    struct Rectangle {
        width: u32,
        height: u32,
    }
    
    fn main() {
        let rect1 = Rectangle { width: 30, height: 50 };
    
        println!("rect1 is {:?}", rect1);
    }
    // 输出:
    // rect1 is Rectangle { width: 30, height: 50 }
    
  • 0
    点赞
  • 0
    收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

御承扬

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值