所以,你決定要學習 Rust。

好的選擇! Rust 是一種很棒的語言,它將系統程式設計的強大功能與現代語言功能相結合,可用於 Web 開發和區塊鏈。

然而,在學習 Rust 時,阻礙者之一正在熟悉它的語法。

在本文中,我將盡力提供一些範例,讓您對它們感到滿意。

入門:變數和類型

讓我們從基礎知識開始:變數。

預設情況下,Rust 變數是不可變的。如果您習慣使用 Python 或 JavaScript 等允許更改變數的語言,這可能聽起來很奇怪。

fn main() {
    let x = 5; // x is immutable by default
    // x = 6; // Uncommenting this will throw a compiler error

    let mut y = 5; // y is mutable
    y = 6; // No problem here
}

注意到let關鍵字了嗎?這就是在 Rust 中聲明變數的方式。如果要變更變數,請使用 mut 關鍵字使其可變。

類型註釋

Rust 具有出色的類型推斷:編譯器通常知道變數的類型。

但有時,您需要自己指定類型:

// Here, we're explicitly saying that z is a 32-bit integer
let z: i32 = 10; 

Rust 的類型系統是它的一大優勢,因此值得儘早熟悉它。

功能

如果您使用過其他語言,那麼 Rust 中的函數看起來非常熟悉。但有一些語法怪癖需要注意。

fn add(a: i32, b: i32) -> i32 {
    a + b // No semicolon means this is the return value
}

請注意,我們使用 -> 來定義函數的傳回類型。另外,這裡沒有 return 關鍵字;如果省略分號,Rust 預設傳回最後一個表達式。

一旦你習慣了就很好了。

Ownership 和 Borrowing

好吧,這就是事情變得有趣的地方。 Rust 的所有權模式使其脫穎而出,但一開始可能會很棘手。

讓我們來看另一個例子

Ownership

在 Rust 中,每個值都有一個變數,即它的所有者。

當所有者超出範圍時,該值就會被刪除。這就是 Rust 避免記憶體洩漏的方法。

fn main() {
    let s1 = String::from("hello");
    let s2 = s1; // Ownership of the String is moved to s2, s1 is now invalid

    // println!("{}", s1); // This would cause a compile-time error
}

這裡,s1 在移動到 s2 後不再擁有該字串。

如果您之後嘗試使用 s1,Rust 不會允許您這樣做。就像 Rust 說的:“嘿,那不再是你的了。”

Borrowing

但是,如果您想使用某個值而不擁有它的所有權怎麼辦?

這就是藉用的用武之地。

fn main() {
    let s1 = String::from("hello");
    let len = calculate_length(&s1); // We're borrowing s1 here

    println!("The length of '{}' is {}.", s1, len);
}

fn calculate_length(s: &String) -> usize {
    s.len()
}

在此範例中,&s1 是對 s1 的reference 。 calculate_length函數暫時借用s1而不取得所有權。函數完成後,s1仍然有效。太酷了。

生命週期

生命週期是 Rust 記錄引用有效時間的方式。

它們最初可能會令人困惑,但它們對於安全記憶體管理至關重要。

讓我們看一個非常基本的範例,以熟悉它。

fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
    if x.len() > y.len() {
        x
    } else {
        y
    }
}

這裡,'a 是生命週期參數。這意味著引用 x 和 y 的生存時間必須至少與傳回值一樣長。這確保我們不會傳回已刪除的內容的引用。

模式匹配

Rust 的 match 語句就像是類固醇的開關。這是我最喜歡的語言部分之一,因為它非常強大且富有表現力。

fn main() {
    let number = 7;

    match number {
        1 => println!("One!"),
        2 => println!("Two!"),
        3 | 4 | 5 => println!("Three, Four, or Five!"),
        6..=10 => println!("Between Six and Ten!"),
        _ => println!("Anything else!"),
    }
}

match 語句根據多個模式檢查一個值,並執行第一個符合模式的程式碼。 _ 是一種包羅萬象的模式,當您想要處理任何未明確匹配的內容時,它非常有用。

使用模式匹配進行解構

您也可以使用match來解構複雜的資料類型,例如元組或枚舉。

fn main() {
    let pair = (2, 5);

    match pair {
        (0, y) => println!("First is zero and y is {}", y),
        (x, 0) => println!("x is {} and second is zero", x),
        _ => println!("No zeroes here!"),
    }
}

這只是表面現象。

Match 可以做更多事情,但這應該為您奠定堅實的基礎。

錯誤處理

Rust 也不例外。相反,它使用 Result 和 Option 類型進行錯誤處理。最初可能會感覺有點冗長,但它比未經檢查的異常安全得多。

fn main() {
    let result = divide(10, 2);
    match result {
        Ok(v) => println!("Result is {}", v),
        Err(e) => println!("Error: {}", e),
    }
}

fn divide(a: i32, b: i32) -> Result<i32, String> {
    if b == 0 {
        Err(String::from("Division by zero"))
    } else {
        Ok(a / b)
    }
}

這裡, Result是一種類型,可以是 Ok(成功)或 Err(錯誤)。這迫使您處理成功和失敗的情況,這對於編寫健全的程式碼非常有用。

?操作員

為了讓錯誤處理更符合人體工學,Rust 提供了?操作員。這是傳播錯誤的簡寫。

fn main() -> Result<(), String> {
    let result = divide(10, 0)?; // If divide returns Err, it returns from the function immediately
    println!("Result is {}", result);
    Ok(())
}

這就是 Rust 的說法,“如果有錯誤,就返回它。”

高級語法:特徵、泛型等

現在我們已經掌握了基礎知識,讓我們深入探討更高階的主題。

特性:介面(有點)

特徵有點像其他語言中的介面。它們定義了不同類型可以實現的共享行為。

trait Summary {
    fn summarize(&self) -> String;
}

struct Article {
    title: String,
    content: String,
}

impl Summary for Article {
    fn summarize(&self) -> String {
        format!("{}: {}", self.title, self.content)
    }
}

在這裡,我們定義並實作了 Article 結構的 Summary 特徵。現在,任何文章都可以進行總結。 Traits 對於編寫通用和可重複使用的程式碼來說非常強大。

泛型:編寫靈活的程式碼

泛型可讓您編寫適用於任何資料類型的函數和類型。

fn largest<T: PartialOrd>(list: &[T]) -> &T {
    let mut largest = &list[0];
    for item in list {
        if item > largest {
            largest = item;
        }
    }
    largest
}

此函數適用於任何可以比較的類型 T。 PartialOrd 部分是特徵綁定的,這意味著 T 必須實作 PartialOrd 特徵,它允許進行排序比較。

實用技巧:寫出慣用的 Rust

  • 使用 rustfmt:Rust 有一個內建的格式化程序,可以讓你的程式碼看起來清晰。只需在專案目錄中執行 Cargo fmt 即可。

  • 使用 Rust 分析器:這個強大的 IDE 擴充功能提供程式碼補全、重構等功能。這就像擁有一個對 Rust 瞭如指掌的助手。

  • Clippy:這是 Rust 的一個 linter,可以捕捉常見錯誤並提出改進建議。執行 Cargo Clippy 看看它發現了什麼。

結論

這篇簡短的文章旨在讓您更加熟悉 Rust。

我有一系列關於這些特定主題的免費影片。

你可以在這裡查看


原文出處:https://dev.to/francescoxx/getting-familiar-with-rusts-syntax-35cd


共有 0 則留言