Rust Struct结构体详解

 更新时间:2022年10月11日 14:25:53   作者:Zheng__Huang  
结构体,是一种自定义数据类型,允许程序员将不同类型的数据结合起来,形成相关联的整体。Rust的结构体还提供方法和关联函数,可以指定那些与结构体数据相关的行为

Defining and Instanting 定义与实例化

使用struct关键字以定义结构体。

struct User {
	id: u64,
	name: String,
	email: String,
	active: bool,
}

使用let语句声明结构体的实例,使用mut指定可变性(必须全部可变或不可变,没有部分可变)

let user1 = User {
    id: 1u64,
    name: String::from("Zheng"),
    email: String::from("888888@outlook.com"),
    active: true,
};

使用.指定结构体成员,如user1.name

如果参数或变量与字段名同名,可以使用简化写法初始化变量

fn new_user(id: u64, name: String, email: String) -> User {
	User { 
		id, 
		name, 
		email, 
		active: true 
	}
}

使用结构体更新语法,可以基于已有实例的字段创建新实例

	let user3 = User {
		id: 3u64,
		..user2
	};

使用..[instant_name]语法,剩余字段将使用user2的字段

Attention: 结构体更新等同于变量赋值,将发生value move,源变量可能导致不可用

let user3 = User {
    id: 3u64,
    ..user2
};
println!("{:#?}", user3);
println!("user2: {:p}; user3: {:p}", &user2, &user3);

以上代码将会产生错误:borrow of a partially moved value。这是由于user2的部分变量(字符串String)被赋值给了user3,导致所有权发生转移,结构体整体(不包括未发生value move的字段)将不再可用。

使用元组结构体可定义匿名字段

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

注意,不同名的相同结构元组结构体将视为不同的类型,无法相互转换

使用空结构体,只实现trait,不需要存储任何数据时可以使用。

结构体数据的所有权:当一个结构体拥有其全部数据的所有权,则只要结构体有效,其数据就有效。如果存在对其他数据的引用,则需要使用生命周期支持。

Derived Traits派生trait

派生trait,指通过derive注解 derive attribute来派生的trait,可以为自定义类型添加许多功能。关于派生trait列表,详见附录C

这里使用Debug trait展示自定义结构体的成员信息。

#[derive(Debug)]
struct User {
	id: u64,
	name: String,
	email: String,
	active: bool,
}
fn main() {
    let user1 = User {
		id: 1u64,
		name: String::from("Zheng"),
		email: String::from("888888@outlook.com"),
		active: true,
	};
    println!("{:#?}", user1);
}
  • 以上代码会显示user1的全部字段信息
  • 也可以使用{:?},单行输出
  • 实际上,它调用了std::fmt::Display,这被包含在派生trait中。

Method 方法

方法是定义在结构体(或枚举类型enumtrait对象)的上下文中的类似函数的过程,第一个参数是self,用于指代调用方法的结构体实例。

Define

需要在impl块中定义方法,

#[derive(Debug)]
struct Rectangle {
	width: u32,
	height: u32,
}
impl Rectangle {
	fn area(&self) -> u32 {
		self.width * self.height
	}
}
fn main() {
	let rect1 = Rectangle {
		width: 30,
		height: 20,
	};
	println!("Size of {:?} is {}", rect1, rect1.area());
}
  • self参数自动拥有impl的结构体类型,不需要另行指定
  • self参数同样拥有可变引用和直接获取所有权
  • 除了方法必须在impl块中,以及第一个参数名必须为self以外,其余与函数相同
  • 可以使用多个impl块来定义方法、关联函数,在泛型和trait中有应用价值

自动引用与解引用

在方法调用中,Rust支持自动引用与解引用,使调用者匹配方法的签名,如添加& &mut *等。

Associated function 关联函数

之前已经提到过,还有不需要接收实例参数的关联函数。因为其不做用于某个结构体实例,所以称其为函数。使用::来使用关联函数。

到此这篇关于Rust Struct结构体详解的文章就介绍到这了,更多相关Rust Struct内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • rust的package,crate,module示例解析

    rust的package,crate,module示例解析

    rust提供了非常优秀的包管理器cargo,我们可以使用crate,module,package来组织代码,这篇文章主要介绍了rust的package,crate,module相关知识,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-04-04
  • 详解Rust 修改源

    详解Rust 修改源

    这篇文章主要介绍了Rust 修改源的相关知识,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧
    2024-01-01
  • Rust生命周期常见误区(中英对照)全面指南

    Rust生命周期常见误区(中英对照)全面指南

    这篇文章主要WEIDJAI 介绍了Rust生命周期常见误区(中英对照)的全面指南,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-11-11
  • Rust调用函数操作符 . 和 :: 的区别详解

    Rust调用函数操作符 . 和 :: 的区别详解

    在Rust中,.和::操作符都可以用来调用方法,但它们的用法有所不同,所以本文就将详细的给大家介绍一下.和::操作符的区别,感兴趣的同学跟着小编一起来学习吧
    2023-07-07
  • Rust-使用dotenvy加载和使用环境变量的过程详解

    Rust-使用dotenvy加载和使用环境变量的过程详解

    系统的开发,测试和部署离不开环境变量,今天分享在Rust的系统开发中,使用dotenvy来读取和使用环境变量,感兴趣的朋友跟随小编一起看看吧
    2023-11-11
  • Rust使用libloader调用动态链接库

    Rust使用libloader调用动态链接库

    这篇文章主要为大家介绍了Rust使用libloader调用动态链接库示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-09-09
  • 一文带你了解Rust是如何处理错误的

    一文带你了解Rust是如何处理错误的

    程序在运行的过程中,总是会不可避免地产生错误,而如何优雅地解决错误,也是语言的设计哲学之一。本文就来和大家来了Rust是如何处理错误的,感兴趣的可以了解一下
    2022-11-11
  • vscode搭建rust开发环境的图文教程

    vscode搭建rust开发环境的图文教程

    本文主要介绍了vscode搭建rust开发环境的图文教程,文中通过图文介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2024-08-08
  • rust中trait的使用方法详解

    rust中trait的使用方法详解

    trait用中文来讲就是特征,它就是一个标记,只不过这个标记被用在特定的地方,也就是类型参数的后面,下面我们就来学习一下trait的具体使用方法吧
    2023-12-12
  • Rust使用Sled添加高性能嵌入式数据库

    Rust使用Sled添加高性能嵌入式数据库

    这篇文章主要为大家详细介绍了如何在Rust项目中使用Sled库,一个为Rust生态设计的现代、高性能嵌入式数据库,感兴趣的小伙伴可以跟随小编一起学习一下
    2024-03-03

最新评论