RUST 0x04 Struct
Posted wr786
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了RUST 0x04 Struct相关的知识,希望对你有一定的参考价值。
RUST 0x04 Struct
1 定义与实例化(Instantiating)Struct
Struct和tuple很像,因为它们都能存储不同的数据类型。但和tuple不同的是,恁需要命名每一个数据。这样做的好处是,struct比tuple更灵活——不需要依靠数据的顺序就能获取某一个特定的值。
例如:
struct User { // 以下的每一项叫做域(field)
username: String,
email: String,
sign_in_count: u64,
active: bool,
}
注意中间用的是,
而不是;
。否则会抛出一个CE。最后一个,
可以不写。
为了使用我们创建的这个struct,我们需要为它创建一个实例,并以key: value
来赋值。我们不必按和上面相同的顺序来,如:
let user1 = User {
email: String::from("someone@example.com"),
username: String::from("someusername123"),
active: true,
sign_in_count: 1,
};
如果想从一个struct中得到某个特定的值,我们可以用.
。如果实例是可变的,那么我们还可用.
对某个特定的域赋值,如:
let mut user1 = User {
email: String::from("someone@example.com"),
username: String::from("someusername123"),
active: true,
sign_in_count: 1,
};
user1.email = String::from("anotheremail@example.com");
值得注意的是,如果要这样做,那么整个实例必须是可变的,Rust不允许只有某几个域是可变的。
我们也可以手写一个初始化函数,如:
fn build_user(email: String, username: String) -> User {
User {
email: email,
username: username,
active: true,
sign_in_count: 1,
}
}
运用简写域初始化(Field Init Shorthand)
为了方便,我们可以用field init shorthand来重写上面的函数:
fn build_user(email: String, username: String) -> User {
User {
email,
username,
active: true,
sign_in_count: 1,
}
}
我们想使email: email,
,因为它们两者有着同样的名称,所以我们可以直接简写为email,
。
运用Struct Update Syntax从其他实例创建实例
如果要创建一个很多值都和一个旧的实例相同的实例,我们可以使用struct update syntax。
首先,是不用update syntax的方法:
let user2 = User {
email: String::from("another@example.com"),
username: String::from("anotherusername567"),
active: user1.active,
sign_in_count: user1.sign_in_count,
};
用update syntax..
,可以以更少的代码实现相同的效果:
let user2 = User {
email: String::from("another@example.com"),
username: String::from("anotherusername567"),
..user1
};
..
→ 剩下的其它域的值将会与给定的实例相同。
Using Tuple Structs without Named Fields to Create Different Types
我们也可以定义长得很像tuple的struct——tuple struct。如:
struct Color(i32, i32, i32);
struct Point(i32, i32, i32);
let black = Color(0, 0, 0);
let origin = Point(0, 0, 0);
Unit-Like Structs Without Any Fields
unit-like struct没有任何域,日后再说。
2 Method Syntax
Method和function很像:它们都是用fn
声明,且都能有参数和返回值。但是method是在struct(或enum等)里定义的,且第一个参数是self
。
定义Method
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()
);
}
impl
→ implementationself
→ self (记得加&(虽然在这个程序里不加也可以)).
→ call Method Syntax
含更多参数的Method
impl Rectangle {
fn area(&self) -> u32 {
self.width * self.height
}
fn can_hold(&self, other: &Rectangle) -> bool {
self.width > other.width && self.height > other.height
}
}
Associated Functions
associated function就是写在impl
里却又不用self
做参数的函数。它们是函数,而不是method。比如String::from
。
associated function经常用来写构造函数,如:
impl Rectangle {
fn square(size: u32) -> Rectangle {
Rectangle { width: size, height: size }
}
}
要调用它,我们需要用::
,比如 let sq = Rectangle::square(3);
Mutiple impl
Blocks
每个struct都可以有多个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
}
}
小结
struct可以用来创建传统类型,将相关的数据存在一起并命名。
method可以用来对struct的实例进行操作。
associated function可以用来创建namespace里的function。
参考
The Rust Programming Language by Steve Klabnik and Carol Nichols, with contributions from the Rust Community : https://doc.rust-lang.org/book/
以上是关于RUST 0x04 Struct的主要内容,如果未能解决你的问题,请参考以下文章