rust学习-结构体

这篇具有很好参考价值的文章主要介绍了rust学习-结构体。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

结构体和元组的区别

结构体需要命名各部分数据以便能清楚的表明其值的意义
结构体比元组更灵活:不需要依赖顺序来指定/访问实例中的值

结构体

// 整个实例可变;Rust 不允许只将某个字段标记为可变
struct User {
    active: bool,
    username: String,
    email: String,
    sign_in_count: u64,
}

let mut user1 = User {
	// 使用自身拥有所有权的 String 类型,而不是 &str 字符串 slice 类型
	// 想要这个结构体拥有它所有的数据
    email: String::from("someone@example.com"),
    username: String::from("someusername123"),
    active: true,
    sign_in_count: 1,
};

user1.email = String::from("anotheremail@example.com");

变量与字段同名时的间写

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

依据其他实例创建实例

fn main() {
    // --snip--
	
	// 设置一个新的 email 值,其余值来自 user1 变量中实例的字段
    let user2 = User {
        email: String::from("another@example.com"),
        // 创建 user2 后不能再使用 user1
        // user1 的 username 字段中的 String 被移到 user2
        // 如果给 user2 的 email 和 username 赋予新 String 值,只使用 user1 的 active 和 sign_in_count 值,
        // 则user1 在创建 user2 后仍然有效
        ..user1
    };
}

元组结构体

没有具体的字段名,只有字段的类型,但有名称,注意元组没名称
元组结构体实例类似于元组:
(1)可以将其解构为单独部分
(2)可以使用 . 后跟索引来访问单独的值

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

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

单元结构体

要在某个类型上实现 trait 但不需要在类型中存储数据
不需要花括号或圆括号
用于特性trait

struct AlwaysEqual;
fn main() {
	// 在 subject 变量中获得 AlwaysEqual 的实例
    let subject = AlwaysEqual;
}

结构体存储被其他对象拥有的数据的引用

错误案例:missing lifetime specifier,丢失生命期标识符

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

fn main() {
    let user1 = User {
    	// 在结构体中存储一个引用而不指定生命周期,无效
        email: "someone@example.com",
        username: "someusername123",
        active: true,
        sign_in_count: 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
}

结构体解决了上述问题

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
}

结构体的打印

Debug trait

// 为结构体显式选择打印调试信息的功能
#[derive(Debug)]
struct Rectangle {
    width: u32,
    height: u32,
}

fn main() {
    let rect1 = Rectangle {
        width: 30,
        height: 50,
    };

    println!("rect1 is {:?}", rect1);   // 平铺打印
    println!("rect1 is {:#?}", rect1); // 类似json格式化的打印
	
	// 更优雅的做法
	// 不希望 dbg! 拥有 rect1 的所有权
	dbg!(&rect1);
}

方法

#[derive(Debug)]
struct Rectangle {
    width: u32,
    height: u32,
}

// impl 块中的所有内容都将与 Rectangle 类型相关联
// Self 类型是 impl 块的类型的别名,注意Self和self区别
impl Rectangle {
    // 在结构体的上下文中被定义
    // &self 实际上是 self: &Self 的缩写
    // 方法可以选择获得 self 的所有权,这里一看就是没有选择
    // 如果想在方法中改变调用方法的实例,需将第一个参数改为 &mut self
    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 Rectangle {
    // 通常,与字段同名的方法将被定义为只返回字段中的值
    fn width(&self) -> bool {
        self.width > 0
    }
}

fn main() {
    let rect1 = Rectangle {
        width: 30,
        height: 50,
    };

    // 在同名方法中使用一个字段来达到任何目的
    // 在 rect1.width 后面加上括号时,Rust 知道指的是方法 width
    // 当不使用圆括号时,Rust 知道指的是字段 width
    if rect1.width() {
        println!("The rectangle has a nonzero width; it is {}", rect1.width);
    }
}

方法的多参

impl Rectangle {
    fn area(&self) -> u32 {
        self.width * self.height
    }

	// self 是否能包裹other
	// 获取另一个 Rectangle 的不可变借用作为参数
    fn can_hold(&self, other: &Rectangle) -> bool {
        self.width > other.width && self.height > other.height
    }
}

关联函数

所有在 impl 块中定义的函数被称为关联函数(associated function)
定义不以 self 为第一参数的关联函数不叫方法
它们不作用于一个结构体的实例,而是直接作用于类型上,比如 String::from 函数,在 String 类型上定义
关联函数经常被用作返回一个结构体新实例的构造函数

impl Rectangle {
    // 定义一个正方形
    fn square(size: u32) -> Rectangle {
        Rectangle {
            width: size,
            height: size,
        }
    }
}

使用结构体名和 :: 语法来调用这个关联函数:

let sq = Rectangle::square(3);

多impl

impl Rectangle {
    fn area(&self) -> u32 {
        self.width * self.height
    }
}

impl Rectangle {
    fn can_hold(&self, other: &Rectangle) -> bool {
        self.width > other.width && self.height > other.height
    }
}

和C++的区别

C/C++ 语言中,有两个不同的运算符来调用方法:
(1). 直接在对象上调用方法,
(2)-> 在一个对象的指针上调用方法,先解引用(dereference)指针

Rust 并没有一个与 -> 等效的运算符
Rust 有一个叫 自动引用和解引用(automatic referencing and dereferencing)的功能(方法调用中有用到):
当使用 object.something() 调用方法时,Rust 会自动为 object 添加 &、&mut 或 *,以便使 object 与方法签名匹配

等价代码:

p1.distance(&p2);
(&p1).distance(&p2);

这种自动引用的行为之所以有效,是因为方法有一个明确的接收者:self 的类型。
在给出接收者和方法名的前提下,Rust 可以明确地计算出方法:
仅读取(&self),做出修改(&mut self)或者是获取所有权(self)

Rust 对方法接收者的隐式借用,让使用所有权的人更少顾虑文章来源地址https://www.toymoban.com/news/detail-564023.html

到了这里,关于rust学习-结构体的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【Rust】Rust学习 第十八章模式用来匹配值的结构

    模式是 Rust 中特殊的语法,它用来匹配类型中的结构,无论类型是简单还是复杂。结合使用模式和  match  表达式以及其他结构可以提供更多对程序控制流的支配权。模式由如下一些内容组合而成: 字面值 解构的数组、枚举、结构体或者元组 变量 通配符 占位符 这些部分描

    2024年02月11日
    浏览(46)
  • 【Rust】Rust学习 第五章使用结构体组织相关联的数据

    定义结构体,需要使用  struct  并为整个结构体提供一个名字。结构体的名字需要描述它所组合的数据的意义。接着,在大括号中,定义每一部分数据的名字和类型,我们称为  字段 ( field )。 实例化(不可变变量) 可变变量 字段初始化简写语法 通过已经存着的变

    2024年02月13日
    浏览(48)
  • rust学习-打印结构体中的vec

    将格式化后的数据写入到一个缓冲区(buffer),而不是直接打印到标准输出或文件中。 这个缓冲区可以是字符串,也可以是需要写入的文件的缓冲区。 writer 参数是一个实现了 std::io::Write trait 的对象,表示要将数据写入到哪里。 format_string 是一个格式化字符串,可以包含占位

    2024年02月12日
    浏览(40)
  • Rust语言从入门到入坑——(2)Rust在windows上搭建开发环境

    开始搭建一个适合在windows上运行的Rust环境。 Rust支持的程序语言很多:可详见官网介绍 本文章主要是在windowns下搭建开发环境 首先,需要安装最新版的 Rust 编译工具和 Visual Studio Code。 Rust 编译工具:https://www.rust-lang.org/zh-CN/tools/install Visual Studio Code:https://code.visualstudio.com

    2024年02月09日
    浏览(52)
  • 【Rust】Rust学习 第十三章Rust 中的函数式语言功能:迭代器与闭包

    Rust 的设计灵感来源于很多现存的语言和技术。其中一个显著的影响就是  函数式编程 ( functional programming )。函数式编程风格通常包含将函数作为参数值或其他函数的返回值、将函数赋值给变量以供之后执行等等。 更具体的,我们将要涉及: 闭包 ( Closures ),一个可以储

    2024年02月12日
    浏览(53)
  • Rust 程序设计语言学习——基础语法

    Rust 语言是一种高效、可靠的通用高级语言。其高效不仅限于开发效率,它的执行效率也是令人称赞的,是一种少有的兼顾开发效率和执行效率的语言。 Rust 语言由 Mozilla 开发,最早发布于 2014 年 9 月。Rust 的编译器是在 MIT License 和 Apache License 2.0 双重协议声明下的免费开源软

    2024年01月22日
    浏览(52)
  • 【从零开始的rust web开发之路 一】axum学习使用

    第一章 axum学习使用 本职java开发,兼架构设计。空闲时间学习了rust,目前还不熟练掌握。想着用urst开发个web服务,正好熟悉一下rust语言开发。 目前rust 语言web开发相关的框架已经有很多,但还是和java,go语言比不了。 这个系列想完整走一遍web开发,后续有时间就出orm,还

    2024年02月12日
    浏览(54)
  • C语言学习笔记——C语言结构

    C语言是一种面向过程的结构化的语言,同时具有高级语言和汇编语言的优点 所有的C语言程序经过编译和连接之后才能被计算机执行 头文件是一种特殊的文件,记录了很多可以直接引用头文件然后使用的函数,也可通过#define声明函数、变量、宏等的定义 头文件通常包含在源

    2024年02月11日
    浏览(46)
  • 软件开发中常用数据结构介绍:C语言队列

    工作之余来写写C语言相关知识,以免忘记。今天就来聊聊 C语言实现循环队列 ,我是分享人M哥,目前从事车载控制器的软件开发及测试工作。 学习过程中如有任何疑问,可底下评论! 如果觉得文章内容在工作学习中有帮助到你,麻烦 点赞收藏评论+关注 走一波!感谢各位的

    2024年02月11日
    浏览(48)
  • C语言——自定义类型结构体_学习笔记

    结构体是一种用户自定义的数据类型,可以包含 多个不同类型的变量 。通过使用结构体,我们可以将相关联的数据组织在一起,便于管理和使用。 在C语言中,结构体(struct)指的是一种数据结构,是C语言中聚合数据类型的一类。 结构体可以包含多个不同类型的数据成员,例

    2024年02月07日
    浏览(41)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包