【Rust】第六节:结构体

0 前言

结构体,struct,听到这个名字大家可能会感觉"哇!好熟悉!",毕竟在大学时学习c/cpp的时候已经接触过很多次了,实际上也确实很类似,即使有些不同,比如"所有权系统"(上一节提到了)、"生命周期"(还没提到)、"模式匹配"(也很熟悉吧)、Trait(还没提到),也大多数是在更后面才会提到。

总体来讲,Ruststruct在语法上与c/cpp类似,但因入了一些新的概念和特性,提供更高级、更安全的编程体验,不过这一节只是认识struct,所以学起来会比较轻松。

原文链接:Rust程序设计语言


1 定义与实例化

让我们来定义和实例化一个结构体

rust 复制代码
// 1 定义
struct User {
    active: bool,
    username: String,
    email: String,
    sign_in_count: u64,
}

fn main() {
    // 2 实例化
    let user0 = User {
        email: String::from("someone@example.com"),
        username: String::from("someusername123"),
        active: true,
        sign_in_count: 1,
    }; // 整个不可变
    
    // 3 实例化可变
    let mut user1 = User {
        email: String::from("someone@example.com"),
        username: String::from("someusername123"),
        active: true,
        sign_in_count: 1,
    }; // 整个可变,不能部分可变

    // 4 可变
    user1.email = String::from("anotheremail@example.com");

    // 5 简便实例化
    // 使用结构体更新语法从其他实例创建实例
    let user2 = User {
        email: String::from("another@example.com"),
        ..user1 // 必须放在最后
    };
}

// 6 函数创建
fn build_user(email: String, username: String) -> User {
    User {
        // 7 简洁创建
        email, // 字段初始化的简洁写法
        username,
        active: true,
        sign_in_count: 1,
    }
}

除了以上方式,还可以没有明明字段的方式来创建,比如:

rust 复制代码
struct Color(i32, i32, i32);
struct Point(i32, i32, i32);

fn main() {
    let black = Color(0, 0, 0);
    let origin = Point(0, 0, 0);
}

但是要注意,虽然ColorPoint的内容看起来一样,但他们是不同的类型!如果你一个函数,入参设定为Color,那么不能用Point

不过,有一个比较复杂的内容是,"所有权","可以使结构体存储被其他对象拥有的数据的引用,不过这么做的话需要用上生命周期(lifetime)",这一点内容会在后面笔记中再展开。


2 示例程序

在这一部分,可以注意:

1、结构体定义

2、创建实例

3、impl关联函数

4、多个关联函数

5、非方法

6、dbg调试

7、函数调用,含入参

rust 复制代码
#[derive(Debug)] // 调试
// 结构体
struct Rectangle {
    width: u32,
    height: u32,
}

// 关联函数
impl Rectangle {
    // self使用,注意"&self"
    fn area(&self) -> u32 {
        self.width * self.height
    }
    // 更多的函数
    fn can_hold(&self, other: &Rectangle) -> bool {
        self.width > other.width && self.height > other.height
    }
}
// 多个关联函数 is ok
impl Rectangle {
    // 不以self为第一参数的关联函数(不是方法)
    // 因为他们并不作用于一个结构体的实例,而是在类型上定义的,就像`String::from`
    // 需要以结构体名和::语法来调用,见下文
    fn square(size: u32) -> Rectangle {
        Rectangle {
            width: size,
            height: sieze,
        }
    }
}

fn main() {
    let rect1 = Rectangle {
        width: 30,
        height: 50,
    };
    
    dbg!(&rect1); // 如果你对调试有兴趣,请阅读原文
    let rect2 = Rectangle {
        width: 10,
        height: 40,
    };
    let rect3 = Rectangle {
        width: 60,
        height: 45,
    };

    // 方法调用
    println!(
        "The area of the rectangle is {} square pixels.",
        rect1.area()
    );
    // 方法调用、参数传入
    println!("Can rect1 hold rect2 ? {}", rect1.can_hold(&rect2));
    // 不是方法,以此种方式调用
    let sq = Rectangle::square(3);
}
相关推荐
CS Beginner3 分钟前
【搭建】个人博客网站的搭建
java·前端·学习·servlet·log4j·mybatis
JavaTree201739 分钟前
【Spring Boot】Spring Boot解决循环依赖
java·spring boot·后端
国服第二切图仔1 小时前
Rust开发之使用anyhow与thiserror简化错误处理
服务器·数据库·rust
cj6341181501 小时前
SpringBoot配置Redis
java·后端
用坏多个鼠标1 小时前
Nacos和Nginx集群,项目启动失败问题
java·开发语言
老程序员刘飞1 小时前
node.js 和npm 搭建项目基本流程
前端·npm·node.js
满天星83035771 小时前
【C++】右值引用和移动语义
开发语言·c++·redis·visual studio
消失的旧时光-19431 小时前
c语言 内存管理(malloc, calloc, free)
c语言·开发语言
歪歪1001 小时前
在C#中除了按属性排序,集合可视化器还有哪些辅助筛选的方法?
开发语言·前端·ide·c#·visual studio
wangbing11252 小时前
开发指南139-VUE里的高级糖块
前端·javascript·vue.js