当前位置:网站首页>rust 中的结构体
rust 中的结构体
2022-06-27 17:58:00 【用户3147702】
1. 引言
此前的文章中,我们已经较为详细的介绍了 Rust 的基本语法:
在许多语言中,我们都早就接触过结构体这种复合数据类型,在面向对象的语言中,类的概念与之非常类似,在 rust 语言中,结构体同样是一种实用且强大的数据类型,那么,在 rust 语言中,结构体这种数据类型要如何定义和使用呢?
2. 结构体的定义
在 rust 中,元组、数组、结构体都是数据的复合结构,他们的不同之处在于:
- 数组:每个元素必须拥有相同的数据类型;
- 元组:每个元素拥有各自的类型;
- 结构体:每个元素拥有各自的类型,且每个元素都需要被命名。
下面是一个典型的结构体的定义:
struct User {
username: String,
email: String,
active: bool
}看起来除了字段命名和类型依据着 rust 独特的语言格式外,其他的方面和其他语言的结构体定义并没有很大的不同。
rust 也允许声明不为任何字段命名的结构体,这样的结构体被称为“元组结构体”,相当于有命名的元组:
struct Color(i32, i32, i32);- 需要注意的是,此处定义使用了 String 类型,而不是 &str 类型,由于 rust 独特的生命周期问题,会造成使用 &str 类型会产生一些麻烦,后续章节将会进一步介绍。
3. 结构体的使用
3.1 示例
let user1 = User {
email: String::from("[email protected]"),
username: String:from("Amy"),
active: true
};
println!("{}'s email is {}", user1.username, user1.email);这是一个典型的结构体的使用。
3.2 可变性
如果我们想要修改结构体变量的某个字段,那就必须将结构体变量声明为可变的 mut:
let mut user1 = User {
email: String::from("[email protected]"),
username: String:from("Amy"),
active: false
};
user1.active = true;- 需要注意的是,rust 不支持单独声明某些字段可变,一旦实例被声明为可变,那么就意味着整个结构体中的任何一个字段均是可变的。
3.3 用语法糖简化结构体使用
1. 变量名与字段名同名时的简化
fn build_user(email: String, username: String) -> User {
User {
email,
username,
active: true
}
}2. 来自其他实例的字段
let user2 = User {
email: String::from("[email protected]"),
username: String::from("Tom"),
..user1
}这里语法 ..user1 表示其余字段均来自于 user1 实例。
4. 方法
在面向对象的语言中,对象除了拥有自己的属性外,往往还要拥有许许多多的行为,这些行为一般被定义为类的 method,也就是方法。
即使是在 C 语言这样的非面向对象的语言中,也可以通过函数指针的方式为结构体添加行为,在 rust 中,同样支持为结构体添加方法。
4.1 定义方法
struct Rectangle {
width: u32,
height: u32,
}
impl 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()
);
}在上述代码中,struct 关键字定义了一个结构体 Rectangle,然后通过 impl 将若干方法与结构体绑定,通过实例的 . 操作符,我们就可以实现方法的调用。
在 impl 块中,我们可以使用 Self 作为原类型的别名。
而针对一个结构体,impl 块并非只能有一个,一个结构体可以拥有很多 impl 块,你甚至可以为每一个方法或是关联函数创建一个单独的 impl 块。
4.2 关联函数
而在impl中定义的不需要传递 &self 参数的函数被称为”关联函数“,非常类似于 java 语言中的 static 方法,例如:
impl Rectangle {
fn square(size: u32) -> Rectangle {
Rectangle {
width: size,
height: size,
}
}
}
fn main() {
let rectangle = Rectangle::square(4);
}如上示例中所写的,结构体的关联函数需要通过结构体类型名与 :: 符号来进行调用。
边栏推荐
- MySQL初学者福利
- 1024 Palindromic Number
- 海底电缆探测技术总结
- What is ICMP? What is the relationship between Ping and ICMP?
- PyCharm常用功能 - 断点调试
- 2022年第一季度消费金融APP用户洞察——总数达4479万人
- Doctoral Dissertation of the University of Toronto - training efficiency and robustness in deep learning
- ABAP随笔-EXCEL-3-批量导入(突破标准函数的9999行)
- NVIDIA Clara-AGX-Developer-Kit installation
- Don't worry. This is the truth about wages in all industries in China
猜你喜欢

crontab的学习随笔

Bit.Store:熊市漫漫,稳定Staking产品或成主旋律

Vs code runs "yarn run dev" and reports "yarn": the file XXX cannot be loaded

Online text batch inversion by line tool

The Fifth Discipline: the art and practice of learning organization

数组练习 后续补充

今晚战码先锋润和赛道第2期直播丨如何参与OpenHarmony代码贡献

2022年第一季度消费金融APP用户洞察——总数达4479万人

openssl客户端编程:一个不起眼的函数导致的SSL会话失败问题

DCC888 :Register Allocation
随机推荐
【建议收藏】ABAP随笔-EXCEL-4-批量导入-推荐
数仓的字符截取三胞胎:substrb、substr、substring
Erreur Keil de Huada Single Chip Computer La solution de Weak
MySQL beginner benefits
On thread safety
在线文本按行批量反转工具
A simple calculation method of vanishing point
華大單片機KEIL報錯_WEAK的解决方案
How to encapsulate and call a library
Cdga | what is the core of digital transformation in the transportation industry?
实战回忆录:从Webshell开始突破边界
binder hwbinder vndbinder
External interrupt experiment based on stm32f103zet6 library function
带你认识图数据库性能和场景测试利器LDBC SNB
Garbage collector driving everything -- G1
基于STM32F103ZET6库函数外部中断实验
谈谈线程安全
2022年第一季度消费金融APP用户洞察——总数达4479万人
爬取国家法律法规数据库
中金证券经理给的开户二维码安全吗?找谁可以开户啊?