列印 hello, world!

YouTube 上觀看本章內容: 影片 1, 影片 2

當你啟動一個新的Rust程式時,它總是有這樣的程式碼。

fn main() {
    println!("Hello, world!");
}
  • fn 的意思是函式,
  • main 是啟動程式的函式。
  • () 表示我們沒有給函式任何變數來啟動。

{} 被稱為程式碼區塊。這是程式碼所在的空間。

println! 是一個列印訊息到控制台(console)的巨集,。一個巨集就像一個為你寫程式碼的函式。巨集名稱後面都有一個 !。我們以後會學習如何建立巨集。現在只要記住有 ! 表示它是一個巨集。

為了學習 ;,我們將建立另一個函式。首先,在 main 中,我們將印出數字 8。

fn main() {
    println!("Hello, world number {}!", 8);
}

println! 中的 {} 的意思是 "把變數放在這裡面"。這樣就會印出 Hello, world number 8!

我們可以像之前一樣,放更多的東西進去。

fn main() {
    println!("Hello, worlds number {} and {}!", 8, 9);
}

這將會印出 Hello, worlds number 8 and 9!

現在我們來建立函式。

fn number() -> i32 {
    8
}

fn main() {
    println!("Hello, world number {}!", number());
}

這個程式也會印出 Hello, world number 8!。當 Rust 觀察到 number() 時,它看到一個函式。這個函式:

  • 沒有用到引數(因為它是 ())
  • 回傳一個 i32->(稱為 "瘦箭")右邊顯示了函式回傳內容的型別

函式內部只有 8。因為行尾沒有 ;,所以這就是它回傳的值。如果它有 ;,它將不會回傳任何東西(意思是它會回傳 ())。如果它有 ;,Rust 將無法編譯,因為回傳的是 i32,而 ; 回傳 (),不是 i32

fn main() {
    println!("Hello, world number {}", number());
}

fn number() -> i32 {
    8;  // ⚠️
}
5 | fn number() -> i32 {
  |    ------      ^^^ expected `i32`, found `()`
  |    |
  |    implicitly returns `()` as its body has no tail or `return` expression
6 |     8;
  |      - help: consider removing this semicolon

這意味著 "你告訴我 number() 回傳的是 i32,但你加了 ;,它就沒回傳值了"。所以編譯器建議去掉分號。

你也可以寫 return 8;,但在Rust中,正常情況下只需將;去掉即可回傳

當你想提供變數給函式時,把它們放在 () 裡。還必須給它們命名並寫上型別。

fn multiply(number_one: i32, number_two: i32) { // 兩個 i32 傳入函式。將它們取名為number_one和number_two。
    let result = number_one * number_two;
    println!("{} times {} is {}", number_one, number_two, result);
}

fn main() {
    multiply(8, 9); // 可以直接給數值
    let some_number = 10; // 或者宣告兩個變數
    let some_other_number = 2;
    multiply(some_number, some_other_number); // 把它們給函式當作引數
}

我們也可以回傳 i32。只要把行尾的分號拿掉就可以了:

fn multiply(number_one: i32, number_two: i32) -> i32 {
    let result = number_one * number_two;
    println!("{} times {} is {}", number_one, number_two, result);
    result // 這是我們要回傳的 i32
}

fn main() {
    let multiply_result = multiply(8, 9); // 我們用multiply()印出結果並回傳給multiply_result
}

宣告變數和程式碼區塊

使用 let 宣告變數(宣告一個變數 = 告訴 Rust 建立一個變數)。

fn main() {
    let my_number = 8;
    println!("Hello, number {}", my_number);
}

變數使用範圍的開始和結束都在程式碼區塊 {} 內。在這個例子中,my_number 在我們呼叫 println! 之前結束,因為它在自己的程式區碼塊裡面。

fn main() {
    {
        let my_number = 8; // my_number 在這裡開始
                           // my_number 在這裡結束!
    }

    println!("Hello, number {}", my_number); // ⚠️ 沒有 my_number,而且
                                             // println!() 也找不到它
}

你可以用程式碼區塊來回傳一個值:

fn main() {
    let my_number = {
    let second_number = 8;
        second_number + 9 // 沒分號,程式碼區塊回傳 returns 8 + 9。
                          // 就像函式一樣運作
    };

    println!("My number is: {}", my_number);
}

如果在程式碼區塊內結束前加上分號,它將回傳 () (沒有值):

fn main() {
    let my_number = {
    let second_number = 8; // 宣告 second_number,
        second_number + 9; // 加 9 到 second_number
                           // 但沒回傳它!
                           // second_number 現在就結束
    };

    println!("My number is: {:?}", my_number); // my_number 會是 ()
}

那麼為什麼我們要寫 {:?} 而不是 {} 呢?我們現在就來談談這個問題。