结构体的定义和实例化
常规结构体
使用 struct
+ 名称+大括号包围的字段集合。初始化时使用 名称+大括号包围的初始化列表,可以不按顺序。
struct Point{
x: i32,
y: i32
}
fn main(){
let pt = Point{
x: 0,
y: 0,
};
}
如果初始化字段跟变量名一样,可以省略
fn get_point(x: i32, y: i32) -> Point{
Point{
x,
y
}
}
如果使用一个相同结构复制部分数据,可以用 ..other
省略
fn get_x_point(input: &Point, x: i32) -> Point{
Point{
x,
..input
}
}
tuple struct
可以定义一个类似于 tuple
的结构,相比于常规结构,只需要省略 字段名。相比于tuple
,只是多了一个名字。也可以称为有名字的 tuple
。
struct Point{i32, i32, i32}
即使两个相同的有名字的tuple
,只要名字不同,他们是两个不同的类型。
空结构
可以定义一个没有任何字段的struct
,与 ()
类似。一般在需要一组特性时使用。
结构的借用
特别的需要注意,在借用结构体字段权限时,字段和整个结构体的权限都被借用,但其他字段不受影响!以下代码是正确的。
struct Point{
x: i32,
y: i32
}
fn main(){
let mut pt = Point{x: 10, y: 20};
let x = &mut pt.x;
let y = &mut pt.y;
*x += 1;
*y += 1;
println!("{}, {}", pt.x, pt.y);
}
输出
要输出一个结构体的内容,可以使结构体继承 Debug
特性,在定义前面加上#[Derive(Debug)]
这样以来,可以使用 {:?}
或者 {:#?}
来打印结构体。
除了使用println!
宏进行打印,还有一个与Debug
相关的宏叫作 dbg!
,它输出参数表达式的内容的同时,将表达式的值返回。
所以可以写以下代码:
let x = 10;
let y = dbg!(x * 10);
dbg!
宏会输出文件名、行号、表达式以及值。
方法(成员函数)
rust
允许给结构定义关联方法,不叫成员函数,也不定义在结构定义中,而是另起一个(或多个)代码块。
使用 imp
关键字加上结构名称来定义,具体函数定义在大括号内即可。对于实例方法,第一个参数使用 self
,&self
,&mut self
等。一般应该不会使用self
。如果第一个参数不是self
则类似于静态函数,使用结构名称+::
+函数名进行调用。
有几个注意点:
-
方法可以视为一般函数的语法糖,完整调用是
Type::method(inst, parameter)
,简写为inst.method(parameter)
。 -
方法可以与字段同名,编译器自动根据有没有参数列表决定是方法还是属性。
-
方法的权限与普通函数一致。
-
可以有多个
imp
块。再加上本身属于语法糖的特性,这意味着,我们可以随意扩充方法,类似于c#
的extention
方法。
- 打赏
- 分享
- 微信
- 支付宝