Rust-07-结构体

结构体

和元组一样,结构体的每一部分可以是不同类型。但不同于元组,结构体需要命名各部分数据以便能清楚的表明其值的意义。由于有了这些名字,结构体比元组更灵活:不需要依赖顺序来指定或访问实例中的值。可以当作是java对象。使用struct关键字定义

定义结构体

rust 复制代码
struct User {
    flag: bool,
    username: String,
    email: String,
    id: u32
}

// 使用没有命名字段的元组结构体来创建不同的类型,称为元组结构体
struct Color(i32, i32, i32);

// 类单元结构体
// 类单元结构体常常在你想要在某个类型上实现 trait 但不需要在类型中存储数据的时候发挥作用。
struct AlwaysEqual;
fn main() {
 let subject = AlwaysEqual;
}

一旦定义了结构体后,为了使用它,通过为每个字段指定具体值来创建这个结构体的 实例。

实例化

rust 复制代码
let mut user = User {
    flag: true,
    username: String::from("tom"),
    email: String::from("hello@email.com"),
    id : 1
};
// 使用.进行访问
user.flag = false;
//结构体更新语法,使用..复用
let user2 = User {
    username: String::from("jerry"),
    ..user
};

//使用没有命名字段的元组结构体来创建不同的类型,称为元组结构体
struct Color(i32, i32, i32);
let black = Color(0, 0, 0);


// 没有任何字段的类单元结构体

示例程序

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
}

方法

方法与函数类似:它们使用 fn 关键字和名称声明,可以拥有参数和返回值,同

时包含在某处调用该方法时会执行的代码。不过方法与函数是不同的,因为它们在结构体的上下文中被定义,并且它们第一个参数总是 self ,它代表调用该方法的结构体实例

rust 复制代码
#[derive(Debug)]
struct Rectangle {
    width: u32,
    height: u32,
}
impl Rectangle {
//这里选择 &self 的理由跟在函数版本中使用 &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 的类型之外,其主要好处在于组织性。我们将某个类型实例能做的所有事情都一起放入 impl 块中,而不是让将来的用户在我们的库中到处寻找 Rectangle 的功能。

在 C/C++ 语言中,有两个不同的运算符来调用方法:. 直接在对象上调用方法,而 -> 在一个对象的指针上调用方法,这时需要先解引用指针。换句话说,如果 object 是一个指针,那么 object->something() 就像(*object).something() 一样。

Rust 并没有一个与 -> 等效的运算符;相反,Rust 有一个叫 自动引用和解引用的功能。方法调用是 Rust 中少数几个拥有这种行为的地方。它是这样工作的:当使用 object.something() 调用方法时,Rust 会自动object 添加 & 、&mut 或 * 以便使 object 与方法签名匹配。这种自动引用的行为之所以有效,是因为方法有一个明确的接收者------------ self 的类型。在给出接收者和方法名的前提下,Rust 可以明确地计算出方法是仅仅读取(&self ) ,做出修改(&mut self )或者是获取所有权(self )

关联函数

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

的 String::from 函数

rust 复制代码
struct Rectangle {
    width:u32,
    height:u32
}

impl Rectangle {
    fn square(size: u32) -> Self {
        Self {
            width: size,
            height: size,
        }
    }
}

fn main() {
    let sq = Rectangle::square(10);
}

关键字 Self 在函数的返回类型中代指在 impl 关键字后出现的类型,在这里是 Rectangle,每个结构体也允许有多个impl块

相关推荐
飞飞-躺着更舒服21 分钟前
【QT】实现电子飞行显示器(改进版)
开发语言·qt
武昌库里写JAVA37 分钟前
Java成长之路(一)--SpringBoot基础学习--SpringBoot代码测试
java·开发语言·spring boot·学习·课程设计
Q_192849990643 分钟前
基于Spring Boot的九州美食城商户一体化系统
java·spring boot·后端
ZSYP-S1 小时前
Day 15:Spring 框架基础
java·开发语言·数据结构·后端·spring
yuanbenshidiaos1 小时前
c++------------------函数
开发语言·c++
程序员_三木1 小时前
Three.js入门-Raycaster鼠标拾取详解与应用
开发语言·javascript·计算机外设·webgl·three.js
是小崔啊2 小时前
开源轮子 - EasyExcel01(核心api)
java·开发语言·开源·excel·阿里巴巴
tianmu_sama2 小时前
[Effective C++]条款38-39 复合和private继承
开发语言·c++
黄公子学安全2 小时前
Java的基础概念(一)
java·开发语言·python