Rust學習筆記(二)|變量、函數與控制流

本篇文章包含的內容

  • 1 變量與常量
  • 2 類型
    • 2.1 標量類型
    • 2.2 復合類型
  • 3 函數
  • 4 控制流
    • 4.1 分支
    • 4.2 循環


1 變量與常量

在Rust中,使用let關鍵字聲明一個變量,變量默認是不可變的。如果要聲明可變變量,需要使用mut關鍵字將其聲明為可變變量。

let x = 1;
x = 2;			// 默認不可變,非法
let x = 2;		// shadow,合法let mut y = 1;
y = 2;

聲明常量需要使用const關鍵字,并且在聲明時必須指明類型。它甚至可以聲明在全局部位,命名需要滿足一定的規則:字母全部大寫,單詞之間用下劃線隔開。

const MAX_POINT : u32 = 100_000;

常量一定是不可變的,所以不需要mut關鍵字聲明,但是它與默認不可變的let聲明的變量有區別。它的賦值結果只能是常量表達式,不能是函數的返回值或者運行時才可以獲得的值。

shadowing(隱藏)是Rust的一個重要特性,它允許新聲明的變量的變量名替代舊變量。這在很大程度上提高了程序的可讀性。被shadow前后的變量類型可以不同。

let spaces = "    ";			// str
let spaces = spaces.len();		// usize,這里返回 4

2 類型

2.1 標量類型

Rust中有四種標量類型(老四樣):

  • 整數:默認i32
  • 浮點:默認f64
  • 布爾:只有兩個值,truefalse,占一個字節。
  • 字符:Unicode標量值,占用4個字節,可以表示中日韓字符,emoji表情等。

整數類型具體可由下表表示。其中isizeusize由操作系統決定,如果操作系統是64位,則isize相當于i64usize相當于u64
請添加圖片描述
整數的表示與C/C++類似,甚至可以添加下劃線以提高可讀性。例如10_00000xA00b1100_0011、甚至可以表示為byte類型(u8 only):b'A'。除了byte類型外,其他整數都可以使用類型后綴,例如57u8。如果整數溢出,Rust僅會在debug編譯模式下panic(恐慌),而在release版本中程序不會panic。

2.2 復合類型

Rust語言中有兩種基礎的復合類型,即元組(Tuple)和數組。元組用小括號表示,數組用中括號表示。元組中的每一個元素可以是不同類型,而數組中的所有元素都必須是同一種類型。無論是元組還是數組,都需要顯式聲明他們的類型。

下面是一個使用元組的例子,可以臨時聲明一個新的元組,例如(x, y, z)來結構獲取舊元組中的每一個成員(Rust會自動推斷xyz的類型)。

fn main() {let tup : (i32, i64, u8) = (1, 2, 3);let (x, y, z) = tup;    // destructureprintln!("{}, {}, {}", x, y, z);println!("{}, {}, {}", tup.0, tup.1, tup.2)
}

使用下面的方法定義一個數組,可以顯式地制定數組元素的類型,也可以讓Rust編譯器自動推斷所需的數組類型。如果訪問的數組索引超出了數組的范圍,編譯可能不會報錯,但是運行時會導致程序panic。

fn main() {let a = [1, 2, 3, 4 , 5];let b: [i32; 5] = [1, 2, 3, 4, 5];let mouths = ["January","February","March","April","May","June","July","August","September","October","November","December"];let arr = [1; 3];   // let arr = [1, 1, 1];println!("{} {}", a[0], b[1]);
}

如果想讓數據存放在stack(棧)內存而不是heap(堆)內存上,或者想要保證有固定數量的元素,則可以使用數組。數組是Stack上分配的單個塊的內存。數組是定長的,而與之對應可變長度的數組稱為Vector(向量)。如果在實際編程中不知道需要使用數組還是Vector,那么一般都需要使用Vector。

3 函數

Rust函數的命名規范采用snake_case規范,即全部小寫,單詞之間用下劃線分開。Rust中的函數定義順序無需尊循C/C++的習慣,即函數必須先聲明再使用,在Rust中,可以將函數的定義放在函數使用之后。函數參數的類型必須指明。

fn main() {another_func(3);
}fn another_func(num: i32) {println!("Another function!");println!("the num is {}", num)
}

Rust是一個基于表達式的語言。任何一個函數體(語句塊,由花括號括起)都由一系列語句組成,可選地,可以由一個表達式結束,函數的返回值就是表達式的值(表達式會產生一個計算值)

與表達式對應的概念稱為語句,一個語句相當于一個命令,語句沒有返回值(它返回一個空的Tuple)。函數的定義也是一個語句,所以它不能當作值賦值給變量(廢話),這一點和C/C++有很大不同(筆者認為相當于修復了C/C++的一個bug?)。函數的定義是語句,但是調用函數(宏)是一個表達式。

let x = (let y = 6);		// 非法let y = {let x = 1;x + 2		// 不能加分號
};println!("the value of y is {}", y);	// 3

對于需要返回值的函數,在->符號后聲明函數返回值的類型,但是不能為返回值命名。在Rust中,函數的返回值就是函數最后一個表達式的值,如果需要提前返回,則可以使用 return 關鍵字,并指定一個值

fn main() {let x = add_five(4);println!("{}", x);		// 9
}fn add_five(num: i32) -> i32 {num + 5// return num + 5;
}

4 控制流

4.1 分支

if表達式后需要添加一個條件,條件必須是bool類型(它不能是一個語句,這一點也與C/C++不同),與if相關聯的代碼稱為分支(arm)。當程序中出現多個else if,則建議只用match語句重構代碼。

fn main() {let x = 3;if x % 2 == 0 {println!("x can be devived by 2");} else if x % 3 == 0 {println!("x can be devived by 3");} else if x % 4 == 0 {println!("x can be devived by 4")}
}

if是一個表達式,所以它可以放在賦值號的右邊。實現類似 ? : ;的效果。需要特別注意的是,ifelse后程序塊的返回值的類型必須相同。

let condition = true;let number = if condition { 5 } else { 6 };		// 5

4.2 循環

Rust中有三種循環:loopwhilefor。其使用方法與C/C++和Python比較類似,但是Rust也提供了一些其他的語法糖。

loop表達式中可以使用break語句打斷循環,并且break語句后可以添加表達式的值來指定loop表達式的返回值:

fn main() {let mut counter = 0;let result = loop {counter += 1;if counter == 10 {break counter * 2;}};println!("result: {}", result);		// 20
}

while循環使用較為簡單,這里不贅述。

遍歷集合元素一般使用for。Rust中同樣存在迭代器的概念。注意,下面的例子中迭代器返回的是數組a的引用,如果直接寫for element in a,則element將會被推斷為i32類型,而不是&i32

fn main() {let a = [1, 2, 3, 4, 5];for element in a.iter() {println!("the value is {}", element);}
}

如果需要代碼執行確定的次數,可以使用標準庫提供的RangeRange可以通過開始數字和結束數字生成一個范圍,但不包含結束數字。可以使用rev()方法獲得反轉的Range

fn main() {for number in (1..4).rev() {println!("{}!", number);}println!("LIFTOFF!");
}

請添加圖片描述


??原創筆記,碼字不易,歡迎點贊,收藏~ 如有謬誤敬請在評論區不吝告知,感激不盡!博主將持續更新有關嵌入式開發、FPGA方面的學習筆記。


本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/93088.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/93088.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/93088.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【渲染流水線】[幾何階段]-[圖元裝配]以UnityURP為例

【從UnityURP開始探索游戲渲染】專欄-直達 前情提要 【渲染流水線】主線索引-從數據到圖像以UnityURP為例-CSDN博客 圖元裝配負責將離散頂點組裝成完整幾何圖元(如點、線、三角形、三角形條帶) (對渲染的探索是個持續不斷完善的過程&#x…

jvm有哪些垃圾回收器,實際中如何選擇?

7.G1收集器一款面向服務端應用的垃圾收集器。 特點如下: 并行與并發:G1能充分利用多CPU、多核環境下的硬 件優勢,使用多個CPU來縮短Stop-The-World停頓時間。部分收集器原本需要停頓Java線程來執行GC動作,G1收 集器仍然可以通過并…

多語言與隱形攻擊:LLM安全防線為何被頻頻突破?

你是否曾以為,只要加裝了“防火墻”,大型語言模型(LLM)就能高枕無憂?Trendoyl 的實際測試卻讓我大吃一驚:即便部署了 Meta 的 Llama Guard,攻擊者還是能輕松用多語種、字符混淆,甚至…

分布式光伏氣象站:為光伏電站的 “氣象感知眼”

分布式光伏氣象站:為光伏電站的 “氣象感知眼”柏峰 【BF-GFQX】在全球能源轉型的浪潮中,分布式光伏發電憑借其就近消納、清潔高效的優勢,成為能源結構優化的重要力量。而分布式光伏氣象站,作為光伏電站的 “智慧感知眼”&#xf…

TCP與UDP:如何選擇最佳傳輸協議

應用場景選擇如果需要可靠傳輸,首選 TCP如果需要傳輸的數據包很大,也首選 TCP絕大部分的場景,都可以優先考慮 TCPUDP 相比于 TCP,最大的優點在于傳輸效率有些情況,既需要可靠性又需要性能,這個時候時候就需…

《Leetcode》-面試題-hot100-棧

題目列表 20. 有效的括號 簡單難度 leetcode鏈接 155. 最小棧 中等難度 leetcode鏈接 394. 字符串解碼 中等難度 leetcode鏈接 739. 每日溫度 中等難度 leetcode鏈接 84. 柱狀圖中最大的矩形 困難難度 leetcode鏈接 題目 (1)有效的括號 題目 給…

GPT-5、Claude-4 同臺亮相!OneEval發布全新“大模型+知識庫”評測白皮書!

OneEval官網地址:http://OneEval.OpenKG.cnOneEval文章鏈接:https://arxiv.org/abs/2506.12577要點導讀 今年4月,OpenKG發布“大模型知識庫”融合能力評估榜單OneEval v1.0。近期,OpenKG在此基礎上,組織撰寫了OneEv…

【最新版】沃德云商協系統全開源+uniapp小程序

一.介紹沃德云商協是一款基于FastAdmin(thinkphp)Uniapp開發的“多組織”的云服務平臺,打造總商會、總協會、總校友會、工商聯等多組織無障礙溝通合作平臺,讓各大分會、各大分校友會、分組織實現輕松管理,線上宣傳展示…

Wireshark專家模式定位網絡故障:14種TCP異常深度解剖

TCP連接如同精密運轉的傳送帶,每一個異常數據包都是故障的早期信號。作為網絡工程師的“外科手術刀”,Wireshark在TCP故障診斷領域的價值無可替代。本文將通過14個真實故障場景,揭示如何利用Wireshark專家系統(Expert System&…

Python Day28 HTML 與 CSS 核心知識點 及例題分析

一、HTML 布局標簽(含 H5 語義化標簽)傳統布局多使用div標簽,H5 新增語義化標簽增強可讀性:核心知識點header:替代div#header,用于頁面頭部(如標題、導航)。footer:替代d…

MySQL 數據庫表操作與查詢實戰案例

MySQL 數據庫表操作與查詢實戰案例 在數據庫學習過程中,熟練掌握表的創建、數據插入及各類查詢操作是基礎且重要的技能。本文將通過實際案例,詳細介紹 MySQL 中數據庫表的設計、數據插入以及常用的查詢操作,幫助初學者快速上手。 項目一&…

THCV215一種高速視頻數據收發器,采用低電壓差分信號(LVDS)技術支持高速串行數據傳輸,支持1080p/60Hz高分辨率傳輸

THCV215 是一款符合 V-by-One HS 標準的 高速視頻數據收發器。THCV215和THCV216被設計為支持主機和顯示器之間的視頻數據傳輸。該芯片組可以在20MHz至100MHz的LVDS時鐘頻率下,僅通過一根差分電纜傳輸39bit視頻數據和3bit同步數據。該芯片組有兩個高速數據通道&#…

Linux 系統下 VS Code 降級至 1.85 版本教程:通過歷史版本網站解決兼容性問題

一、問題背景 當前使用的 VS Code 版本為 1.102.3,這一版本可能是未來版本、內部測試版或 Insiders 版本,而目前最新的穩定版屬于 1.8x 系列。由于版本過新,可能導致與部分插件(如舊版 Remote-SSH)或系統環境不兼容。…

一個基于 PyTorch 的完整模型訓練流程

一個基于 PyTorch 的完整模型訓練流程 flyfish訓練步驟具體操作目的1. 訓練前準備設置隨機種子、配置超參數(batch size、學習率等)、選擇計算設備(CPU/GPU)確保實驗可復現;統一控制訓練關鍵參數;利用硬件加…

ffmpeg,ffplay, vlc,rtsp-simple-server,推拉流命令使用方法,及測試(二)

一、常用命令 ffmpeg 推流命令 : ffmpeg -re -i input.mp4 -c copy -f flv rtmp://39.105.129.233/myapp/ffmpeg -re -i input.mp4 -c copy -f flv rtsp://39.105.129.233/myapp/-re 讀取流 -i 輸入文件 -f # 指定推流formatffplay 拉流命令 : ffplay rtmp://39.105.129.233/m…

使用行為樹控制機器人(三) ——通用端口

文章目錄一、通用端口功能實現1. 功能實現1.1 頭文件定義1.2 源文件實現1.3 main文件實現1.4 tree.xml 實現2. 執行結果使用行為樹控制機器人(一) —— 節點使用行為樹控制機器人(二) —— 黑板使用行為樹控制機器人(三) —— 通用端口有了上述前兩節我們已經可以實現節點間的通…

DataDome反爬蟲驗證技術深度解析:無感、滑塊與設備驗證全攻略

DataDome反爬蟲驗證技術深度解析:無感、滑塊與設備驗證全攻略 隨著網絡安全威脅的不斷演進,企業對數據保護的需求日益增強。DataDome作為業界領先的反爬蟲解決方案,以其三層防護機制在眾多知名網站中得到廣泛應用。本文將深入解析DataDome的…

RabbitMQ 消息轉換器詳解

RabbitMQ 消息轉換器詳解 一、為什么需要消息轉換器? RabbitMQ 的消息傳輸協議只識別字節流: 發送對象時,需要序列化成字節數組接收消息時,需要將字節數組反序列化成對象 如果不使用消息轉換器: 需要手動序列化和反序列…

內網穿透的應用-告別“現場救火”!用 cpolar遠程調試讓內網故障排查進入“云時代”

文章目錄前言**常見困境與解決方案****實際應用價值**1. Remote JVM Debug2. 系統要求與環境準備2.1 服務器環境2.2 本地開發環境3. 內網服務器準備及開始3.1 安裝cpolar配置支持遠程ssh登錄3.1.1 什么是cpolar?3.1.2 安裝cpolar3.1.3 注冊及配置cpolar系統服務3.1.…

Cherryusb UAC例程對接STM32內置ADC和PWM播放音樂和錄音(下)=>UAC+STM32 ADC+PWM實現錄音和播放

1. 程序基本框架整個程序框架, 與之前的一篇文章《Cherryusb UAC例程對接STM32內置ADC和DAC播放音樂和錄音(中)>UACSTM32 ADCDAC實現錄音和播放》基本一致, 只是這次將DAC替換成了PWM。因此這里不再贅述了。 2. audio_v1_mic_speaker_multichan_template.c的修改說明(略) 參…