寫一個使用 struct 的範例程式

使用 Rust 寫一個計算長方形面積的程式。

fn main() {
    let width1 = 30;
    let height1 = 30;

    println!(
        "The area of the rectangle is {} square pixels.",
        area(width1, height1)
    );
}

fn area(widht: u32, height: u32) -> u32 {
    width * height
}

上面的函式 area() 的參數為長方形的長與寬,雖然意思是這樣,但從程式碼的設計上卻看不出這一點。

試著使用元組類型重構。

fn main() {
    let rect1 = (30, 50);

    println!(
        "The area of the rectangle is {} square pixels.",
        area(rect1)
    );
}

fn area(dimensions: (u32, u32)) -> u32 {
    dimensions.0 * dimensions.1
}

雖然只需要一個參數,但誰是長誰是寬反而看不出來,這時候我們可以使用 struct 來解決這個問題。

struct Rectangle {
    width: u32,
    height: u32,
}

fn main() {
    let rect1 = Rectangle { width: 30, height: 50 };

    println!(
        "The area of the rectangle is {} square pixels.",
        area(&rect1)
    );
}

fn area(rectangle: &Rectangle) -> u32 {
    rectangle.width * rectangle.height
}

使用 struct 可以組合一組相關聯的參數,並給這些參數賦予命名,使其他人能更容易理解這段程式碼在做什麼。

通過 Derived Trait 增加實用的功能

嘗試一下印出 Rectangle struct 的值。

struct Rectangle {
    width: u32,
    height: u32,
}

fn main() {
    let rect1 = Rectangle { width: 30, height: 50 };

    println!("rect1 is {}", rect1); // error: the trait `std::fmt::Display` is not implemented for `Rectangle`
}

雖然 println! 能夠印出很多類型 (例如數字與字串),不過 {} 默認使用被稱為 Display 的格式。

不過 Rectangle 並沒有提供 Display 格式,println! 會不知道該用什麼格式印出。

這個時候我們可以使用 {:?},代表我們要使用 Debug 的格式印出 Rectangle

println!("rect1 is {:?}", rect1);

Debug 是一個 trait,它允許我們以一種對開發者有幫助的方式印出 struct。

但上述的打印方式依舊行不通,會出現以下的錯誤。

  = help: the trait `Debug` is not implemented for `Rectangle`
  = note: add `#[derive(Debug)]` to `Rectangle` or manually `impl Debug for Rectangle`
  = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider annotating `Rectangle` with `#[derive(Debug)]`

Rust 確實包含為 struct 印出其結構的功能,但是我們必須在程式碼中註明要為 struct 使用這個功能。

因此在 struct 前面,我們必須要加上 #[derive(Debug)]

#[derive(Debug)]
struct Rectangle {
    width: u32,
    height: u32,
}

fn main() {
    let rect1 = Rectangle { width: 30, height: 50 };

    println!("rect1 is {:?}", rect1);
}

使用註解來派生 Debug 的 trait,就可以使用除錯格式印出 Rectangle 實例

不過印出來的格式並不是很漂亮。

rect1 is Rectangle { width: 30, height: 50 }

我們可以使用 {:#?},那麼最後印出來的結果就會經過排版。

rect1 is Rectangle {
    width: 30,
    height: 50
}

This site uses Just the Docs, a documentation theme for Jekyll.