概述
Rust作為一種系統編程語言,近年來在開發者社區中逐漸嶄露頭角。其獨特的所有權系統和內存安全特性,使得Rust在高性能、併發編程領域具有顯著優勢。本文將深入介紹Rust的一些基礎語法,幫助大家快速掌握這門高效、安全的編程語言。
基本數據類型
Rust中的基本數據類型分為:標量類型和複合類型。
標量類型包括下面幾種:
1、整數類型。有符號整數:i8、i16、i32、i64、i128,以及平台相關的 isize(根據目標機器是32位還是64位系統,其大小分別為32位或64位)。無符號整數:u8、u16、u32、u64、u128,以及平台相關的 usize(同樣依賴於目標平台的字長)。
2、浮點數類型。單精度浮點數:f32。雙精度浮點數:f64。
3、布爾類型。表示真假值:bool,僅有兩個可能的值:true和false。
4、字符類型。Unicode碼點:char,在Rust中每個字符佔用四個字節。
複合類型包括下面幾種:
1、元組(Tuples):元組可以容納多個不同類型的值,比如:(i32, f64, bool)。
2、數組:固定長度的同類型元素集合,比如:[i32; 5]表示一個包含5個i32類型元素的數組。
3、結構體:用户自定義的數據類型,用於將多個字段組合成一個新的類型。可參考下面的Point結構體。
struct Point {
x: i32,
y: i32,
}
另外,Rust還提供了枚舉、引用、切片、智能指針等更復雜的複合類型。同時,字符串類型(String)雖然不是基本類型,但在實際編程中經常使用,它是一個可變的、擁有UTF-8編碼文本的動態數組。
變量
變量通過let關鍵字聲明,並且可以在聲明時初始化。變量的聲明方式如下:
let variable_name: type = value;
其中,variable_name是變量的名稱,type是變量的類型,value是變量的初始值。由於Rust支持自動類型推導,這意味着在某些情況下,編譯器可以根據變量的初始化表達式來確定其類型,而不用顯式地聲明類型type。
let a = 66;
let b: i32 = 99;
Rust中的變量默認是不可變(immutable)的,即一旦被賦值,後續不能更改其值。
let a = 66;
// 會出現編譯錯誤:cannot assign twice to immutable variable
a = 99;
如果需要使變量可變,需要使用mut關鍵字來進行聲明。
let mut a = 66;
a = 99;
常量
常量在Rust中使用const關鍵字進行聲明,其值在編譯時就必須確定,且在整個程序的生命週期中都不能改變。常量的聲明方式如下:
const constant_name: type = value;
其中,constant_name是常量的名稱,type是常量的類型,value是常量的值。與變量類似,由於Rust支持自動類型推導,type可以省略。注意:常量只能被設置為常量表達式,而不能是函數調用的結果,或其他任何只能在運行時計算出的值。
const MATH_PI: f64 = 3.1415926;
條件判斷
Rust使用if、else if、else關鍵字來進行條件判斷,這些關鍵字允許你根據條件表達式的值來執行不同的代碼塊。注意:else if和else塊是可選的,並且可以根據需要添加任意數量的else if塊。
條件表達式的結果必須是一個布爾值,也就是為true或false。如果條件為真,則執行if塊中的代碼。如果條件為假,並且存在else塊,則執行else塊中的代碼。如果存在else if塊,則繼續檢查下一個條件,直到找到一個為真的條件或者遍歷完所有條件。
另外,Rust的條件語句必須使用大括號{}來定義代碼塊,即使代碼塊只包含一行也是如此。這是Rust語法的一個特點,有助於清晰地標識代碼塊的開始和結束。
let score = 85;
if score > 90 {
println!("Excellent");
} else if score > 75 {
println!("Good");
} else if score > 50 {
println!("Pass");
} else {
println!("Fail");
}
循環語句
在Rust中,循環語句主要有以下三種形式:for循環、while循環、loop循環。下面分別進行介紹。
1、for循環:用於遍歷任何實現了IntoIterator特性的集合,比如:數組、切片、元組、迭代器等。
let numbers = [1, 2, 3, 4, 5];
for number in numbers.iter() {
println!("Number: {}", number);
}
另外,還可以使用範圍(range)來創建一個迭代器進行循環,可參考下面的示例代碼。注意:範圍0..5,不包括最後的5。
for i in 0..5 {
println!("Number: {}", i + 1);
}
2、while循環:會一直執行其循環體內的代碼,直到給定的條件變為false為止。
let mut number = 0;
while number < 5 {
println!("Number: {}", number + 1);
number += 1;
}
3、loop循環:是一個無限循環,它沒有預設的退出條件,需要顯式地使用break關鍵字來終止循環。
let mut number = 0;
loop {
if number > 3 {
break;
}
println!("Number: {}", number + 1);
number += 1;
}
除此之外,Rust還支持使用標籤來控制循環的跳轉。標籤是一個標識符,後面跟着一個冒號,它可以放在循環之前,然後你可以使用break或continue語句與標籤一起使用,來控制循環的跳轉。
'outer: loop {
for i in 1..5 {
if i == 3 {
break 'outer;
}
println!("Number: {}", i);
}
}
println!("Exited the loop");
在上面的示例代碼中,我們有一個外層loop循環和一個內層for循環。當i等於3時,break 'outer語句會執行,從而退出帶有標籤'outer的外層循環。
函數
在Rust中,函數是程序的基本構建塊之一,用於封裝和重用代碼。Rust中的函數使用fn關鍵字聲明,可以接收參數並返回結果。函數可以有任意數量的參數,並且每個參數都有其類型註解。函數可以返回一個值(通過 -> 後跟返回類型指定),也可以不返回任何值(在這種情況下,函數的返回類型為 (),表示空元組)。
fn greet(name: &str) -> String {
let msg = format!("Hello, {}!", name);
msg
}
fn main() {
let msg = greet("World");
println!("{}", msg);
}
在上面的示例代碼中,greet函數接收一個字符串引用作為參數,並返回一個格式化後的字符串。main函數調用了greet函數,接受其返回值,並打印了msg。
註釋
註釋是用來解釋和説明代碼功能、用法和設計決策的文字內容,它們不會被編譯器編譯成程序的一部分。Rust中的註釋分為以下三種類型。
單行註釋: 單行註釋以兩個斜槓(//)開始,直到該行結束為止的所有文本都會被編譯器忽略。
// 這是一個單行註釋
let a = 66; // 這裏也可以添加一個單行註釋
多行註釋: 多行註釋使用三個斜槓(///)開頭,可以跨越多行。特別的是,當這樣的註釋出現在模塊、函數、結構體、枚舉等定義的前面時,它們會被編譯器用來生成API文檔。這種類型的註釋遵循Markdown格式,可以包含更豐富的文本格式和代碼示例。
/// 文檔註釋示例,用於描述函數功能
///
/// # 示例
///
/// ```
/// let result = my_func(42);
/// println!("結果: {}", result);
/// ```
fn my_func(num: i32) -> i32 {
num* 2
}
文檔註釋:可以通過cargo doc命令來生成HTML格式的API文檔,這對於開源項目或團隊協作非常有用,因為它可以幫助其他開發者快速瞭解庫或項目的接口及其使用方法。
宏
Rust的宏是一種編譯時的代碼生成工具,它允許在編寫代碼時使用宏來自動生成代碼,從而提高代碼的可讀性、可維護性和重用性。Rust的宏系統是基於macro_rules!關鍵字實現的,它提供了兩種主要的宏類型:聲明性宏和程序宏。
聲明式宏:這種宏基於規則匹配,利用簡單的語法模式來捕獲並替換代碼片段。聲明式宏是通過macro_rules!關鍵字來定義的,它們主要用於處理簡單的文本轉換,比如:創建簡化的日誌宏,或構建某些特定模式的函數調用。
macro_rules! add {
($a:expr,$b:expr)=>{
{
$a + $b
}
}
}
fn main() {
let result = add!(66, 99);
println!("{}", result);
}
程序宏:程序宏提供了更復雜的代碼生成能力,允許在編譯時執行任意的Rust代碼。程序宏分為幾種類型,包括:自定義派生宏、屬性類宏和函數式宏。這些宏允許更高級的代碼生成和轉換,但也需要更復雜的定義和實現。
💡 如果想閲讀最新的文章,或者有技術問題需要交流和溝通,可搜索並關注微信公眾號“希望睿智”。