在rust中创建一个结构struct貌似很简单,也很容易获取到属性值。那么该怎么使用呢?是否涉及到所有权呢?如果涉及到又该如何处理呢?
首先通过一个求矩形周长的示例来逐步深入:
fn main() {
let width = 36;
let height = 18;
println!("宽为:{},高为:{}的矩形的周长为:{}", width, height, get_perimeter(width, height))
}
fn get_perimeter(width: u32, height: u32) -> u32 {
(width + height) * 2
}
cargo run
宽为:36,高为:18的矩形的周长为:108
用元组重构:
获取周长函数计算一个矩形的周长,但是我们编写的函数有两个参数。而参数又是相关联的,但是在上述例子中并没有任何一处来表达。将宽度与高度组合在一起会不会更简单一点呢,比如方便管理与容易理解,不妨借助tuple试试:
fn main() {
let rect1 = (36,18);
println!("宽高:{:?}的矩形的周长为:{}", rect1, get_perimeter(rect1))
}
fn get_perimeter(dimensions: (u32, u32)) -> u32 {
(dimensions.0 + dimensions.1) * 2
}
cargo run
宽高:(36, 18)的矩形的周长为:108
在某种程度上,该方法比最开始的要好。 元组让我们增加了一些结构,现在我们只传递一个参数。 但以最开始的方式,这个方法有有些不清晰:元组没有命名其元素,导致我们的计算变得更加混乱,因为我们必须索引元组的各个部分。
我们是否要混合宽度和高度以进行面积计算并不重要,但是如果我们想在屏幕上绘制矩形,那就很重要了! 我们必须得记住,width是元组索引0,height是元组索引1。如果其他人在编写此代码,则他们必须弄清楚这一点并牢记在心。 容易忘记或混淆这些值并导致错误,因为我们没有在代码中传达数据的含义。
用结构重构:添加更多含义
我们使用结构通过标记数据来添加含义。 我们可以将正在使用的元组转换为具有整体名称和部分名称的数据类型,如下示例:
#[derive(Debug)]
struct Rectangle {
width: u32,
height: u32,
}
fn main() {
let rect1 = Rectangle {
width: 36,
height: 18,
};
println!("矩形:{:?}的矩形的周长为:{}", rect1, get_perimeter(&rect1))
}
fn get_perimeter(rectangle: &Rectangle) -> u32 {
(rectangle.width + rectangle.height) * 2
}
cargo run
矩形:Rectangle { width: 36, height: 18 }的矩形的周长为:108
通过上例可以清楚地看到我们的程序变得清晰简洁且便于理解了,此处由于只是借用一下矩形的宽高的数据并不对其进行更改,所以使用的时候必须借助&来实现,在此处设计到了所有权的问题,如果没有借用&的话,会导致空指针的问题,如下所示:
cargo run
|
12 | println!("矩形:{:?}的矩形的周长为:{}", rect1, get_perimeter(rect1))
| --------------------------------------------------------------^^^^^--
| | | |
| | | move out of `rect1` occurs here
| | borrow of `rect1` occurs here
| borrow later used here
error: aborting due to previous error
For more information about this error, try `rustc --explain E0505`.
error: could not compile `cargo_learn`.
To learn more, run the command again with --verbose.
以上,就是对struct的一个实际运用的初级探索。