【Rust 精進之路之第4篇-數據基石·上】標量類型:整數、浮點數、布爾與字符的精妙之處

系列: Rust 精進之路:構建可靠、高效軟件的底層邏輯
作者: 碼覺客
發布日期: 2025-04-20

引言:構成萬物的“原子”——標量類型

在上一篇文章【變量觀】中,我們深入探討了 Rust 如何通過 letmutconststatic 和 Shadowing 來管理變量綁定,并理解了其背后對安全性和清晰性的重視。我們知道了如何為數據命名和設定規則,現在,是時候看看這些變量“盒子”里具體能裝些什么了。

任何復雜的程序,歸根結底都是由最基礎的數據單元構成的。在 Rust 中,這些最基礎的、不可再分的數據類型被稱為標量類型 (Scalar Types)。它們是構成更復雜數據結構(如數組、結構體)的“原子”。Rust 的標量類型主要有四種:整數 (Integers)、浮點數 (Floating-Point Numbers)、布爾值 (Booleans) 和字符 (Characters)

你可能覺得這些類型在其他語言里也司空見慣,但在 Rust 中,即使是這些基礎類型,也蘊含著其獨特的設計考量,特別是在類型安全、內存表示和行為定義(如整數溢出處理)方面。理解這些細節,對于編寫精確、高效且健壯的 Rust 代碼至關重要。本文將帶你逐一解剖這四大標量類型,探索它們在 Rust 世界中的精妙之處。

一、整數類型 (Integer Types):精確的大小與溢出處理

整數是沒有小數部分的數字。Rust 提供了一系列內置的整數類型,它們的主要區別在于位寬 (bit width)是否有符號 (signedness)

  • 有符號整數 (Signed Integers): 類型名稱以 i 開頭 (代表 integer),可以表示正數、負數和零。它們使用二進制補碼 (Two’s Complement) 表示法。
    • i8, i16, i32, i64, i128: 分別占用 8, 16, 32, 64, 128 位內存空間。
    • isize: 其大小取決于目標計算機的架構(32位系統上是 32 位,64位系統上是 64 位)。主要用于指針偏移量集合索引
  • 無符號整數 (Unsigned Integers): 類型名稱以 u 開頭 (代表 unsigned),只能表示非負數(零和正數)。
    • u8, u16, u32, u64, u128: 同樣分別占用 8, 16, 32, 64, 128 位內存空間。
    • usize: 大小同樣取決于目標架構,與 isize 對應。所有集合類型(如數組、Vec、切片)的索引都必須是 usize 類型。這是因為索引代表內存偏移量,其最大值不能超過地址空間的大小。

表示范圍:
一個 n 位的有符號整數可以表示從 -(2^(n-1))2^(n-1) - 1 的數。
一個 n 位的無符號整數可以表示從 02^n - 1 的數。
例如,i8 的范圍是 -128 到 127,而 u8 的范圍是 0 到 255。

整數的字面量表示 (Integer Literals):
Rust 支持多種格式的整數常量寫法:

fn main() {let decimal = 98_222;       // 十進制 (Decimal) - 下劃線可作為視覺分隔符,不影響值let hex = 0xff;           // 十六進制 (Hex) - 以 0x 開頭let octal = 0o77;         // 八進制 (Octal) - 以 0o 開頭let binary = 0b1111_0000; // 二進制 (Binary) - 以 0b 開頭let byte = b'A';          // 字節 (Byte) - 僅適用于 u8,表示 ASCII 字符的字節值println!("Decimal: {}", decimal); // 輸出: 98222println!("Hex: {}", hex);       // 輸出: 255println!("Octal: {}", octal);     // 輸出: 63println!("Binary: {}", binary);   // 輸出: 240println!("Byte (u8): {}", byte);   // 輸出: 65 (A 的 ASCII 值)// 整數類型后綴let big_number = 3_000_000_000u64; // 顯式指定為 u64println!("Big number: {}", big_number);// usize 示例let array = [1, 2, 3];let index: usize = 1; // 索引必須是 usize 類型println!("數組第二個元素: {}", array[index]); // 輸出: 2
}

整數的默認類型:
如果在沒有足夠上下文讓編譯器推斷類型的情況下使用整數常量,Rust 會默認將其視為 i32。這是因為 i32 在大多數現代處理器上性能良好,并且其大小適中,適用于很多常見場景。

關鍵點:整數溢出 (Integer Overflow)

當一個整數運算的結果超出了該類型所能表示的范圍時,就會發生溢出。例如,一個 u8 類型的變量最大能存 255,如果你給它加 1,結果會是什么?

Rust 對待整數溢出的方式取決于構建模式

  1. 調試模式 (Debug Build - cargo buildcargo run):

    • 如果發生整數溢出,程序會立即 panic (崩潰)
    • 目的: 在開發階段盡早發現這類潛在錯誤。Rust 把溢出視為一種邏輯錯誤,默認行為是安全優先。
  2. 發布模式 (Release Build - cargo build --release):

    • 如果發生整數溢出,Rust 不會 panic,而是執行二進制補碼環繞 (Two’s Complement Wrapping)
    • 例如: 對于 u8 類型,255 + 1 會變成 0255 + 2 會變成 1,就像一個循環計數器。對于有符號整數也是類似的環繞行為。
    • 目的: 性能優先。檢查每次整數運算是否溢出是有運行時開銷的。發布模式假設開發者已經處理了或接受了溢出的可能性,并選擇了性能更高的行為。

顯式處理溢出:
Rust 強烈不建議依賴隱式的環繞行為,因為它可能隱藏邏輯錯誤。相反,標準庫提供了一系列方法讓你顯式地控制溢出行為:

  • wrapping_* 方法: 執行環繞(與 release 模式行為一致),如 wrapping_add()
  • checked_* 方法: 如果發生溢出,返回 None;否則返回包含結果的 Some。這允許你檢查并處理溢出情況。如 checked_add()
  • overflowing_* 方法: 返回一個包含結果和表示是否發生溢出的布爾值的元組。如 overflowing_add()
  • saturating_* 方法: 如果發生溢出,結果會停留在該類型的最大值或最小值(飽和)。如 saturating_add()
fn main() {let a: u8 = 250;let b: u8 = 10;// 1. Wrapping (環繞)let wrapped_sum = a.wrapping_add(b); // 250 + 10 = 260 -> 260 % 256 = 4println!("Wrapping add: {}", wrapped_sum); // 輸出: 4// 2. Checked (檢查)let checked_sum = a.checked_add(b);match checked_sum {Some(sum) => println!("Checked add: {}", sum),None => println!("Checked add: Overflow occurred!"), // 輸出: Overflow occurred!}let checked_sum_safe = (100u8).checked_add(20u8);if let Some(sum) = checked_sum_safe {println!("Safe checked add: {}", sum); // 輸出: 120}// 3. Overflowing (溢出指示)let (overflowing_sum, did_overflow) = a.overflowing_add(b);println!("Overflowing add: result={}, overflow={}", overflowing_sum, did_overflow); // 輸出: result=4, overflow=true// 4. Saturating (飽和)let saturated_sum = a.saturating_add(b); // 結果停留在 u8 的最大值 255println!("Saturating add: {}", saturated_sum); // 輸出: 255
}

設計哲學思考: Rust 對整數溢出的處理方式體現了其在安全與性能之間的權衡,以及對開發者意圖明確性的要求。默認在 debug 模式 panic 保證了開發時的安全發現,而在 release 模式提供性能選項(環繞),同時通過 checked_* 等方法賦予開發者完全的、顯式的控制權。

二、浮點數類型 (Floating-Point Types):近似的藝術

浮點數用于表示帶有小數部分的數字。Rust 提供了兩種基礎的浮點數類型,它們都遵循 IEEE 754 標準

  • f32 單精度浮點數,占用 32 位。
  • f64 雙精度浮點數,占用 64 位。

默認類型:
Rust 的浮點數默認類型是 f64。這是因為在現代 CPU 上,f64 的運算速度通常與 f32 相當,甚至有時更快,并且 f64 提供了更高的精度。除非你有特定的理由(例如需要節省內存,或者與只支持 f32 的硬件/庫交互),否則推薦使用 f64

fn main() {let x = 2.0; // 默認推斷為 f64let y: f32 = 3.0; // 顯式指定為 f32println!("x (f64): {}", x);println!("y (f32): {}", y);// 浮點數運算let sum = x + 1.5; // f64 + f64println!("Sum: {}", sum);// 注意:不同浮點數類型之間不能直接運算,需要顯式轉換// let mixed_sum = x + y; // 編譯錯誤!類型不匹配 (expected f64, found f32)let converted_y = y as f64; // 使用 as 進行類型轉換let mixed_sum_correct = x + converted_y;println!("Correct mixed sum: {}", mixed_sum_correct);
}

浮點數的“陷阱”:精度問題

由于浮點數在計算機內部使用二進制表示,很多十進制小數無法被精確表示,只能是一個近似值。這會導致一些看似奇怪的行為:

fn main() {let a = 0.1; // f64let b = 0.2; // f64let sum = a + b;println!("0.1 + 0.2 = {}", sum); // 可能輸出類似 0.30000000000000004// 因此,直接比較浮點數是否相等通常是不可靠的// assert_eq!(sum, 0.3); // 這行代碼很可能會 panic!// 正確的做法是比較差值是否在一個很小的容差 (epsilon) 內let difference = (sum - 0.3).abs();let epsilon = 1e-10; // 定義一個很小的容差值if difference < epsilon {println!("浮點數比較:認為 0.1 + 0.2 等于 0.3 (在容差范圍內)");} else {println!("浮點數比較:認為 0.1 + 0.2 不等于 0.3");}// 特殊值:NaN (Not a Number)let result = (-42.0_f64).sqrt(); // 對負數開平方根得到 NaNprintln!("sqrt(-42.0) = {}", result); // 輸出: NaN// 注意:NaN 不等于任何值,包括它自己!(result == result) 會是 falseassert!(result.is_nan()); // 應該使用 is_nan() 方法來檢查
}

核心建議: 在進行浮點數計算時,要時刻意識到精度限制。避免直接進行相等性比較。對于需要精確計算的場景(如金融計算),考慮使用專門的定點數庫或十進制算術庫(如 rust_decimal crate)。

三、布爾類型 (Boolean Type):真與假的裁判

布爾類型 bool 是最簡單的類型之一,它只有兩個可能的值:truefalse

fn main() {let is_rust_fun: bool = true;let is_learning_easy = false; // 類型推斷為 boolprintln!("Rust 有趣嗎? {}", is_rust_fun); // 輸出: trueprintln!("學習輕松嗎? {}", is_learning_easy); // 輸出: false// 布爾值主要用于條件控制流if is_rust_fun {println!("太棒了,繼續學習!");} else {println!("再堅持一下,你會發現它的魅力!");}// 強調:Rust 是強類型語言,布爾值不能隱式轉換成整數(反之亦然)// let number = is_rust_fun as i32; // 可以顯式轉換,true 變為 1, false 變為 0// if 1 { ... } // 編譯錯誤!if 條件必須是 bool 類型
}

布爾類型在內存中通常占用 1 個字節。它的簡單性背后是邏輯判斷的基礎,是構建復雜程序流程控制的關鍵。Rust 的強類型系統確保了條件表達式必須明確地產生 bool 值,避免了 C/C++ 中將整數誤用作布爾值可能引發的錯誤。

四、字符類型 (Character Type):Unicode 的世界

Rust 的 char 類型代表一個單一的 Unicode 標量值 (Unicode Scalar Value)。這意味著一個 char 可以表示遠超 ASCII 范圍的字符,包括各種語言的字母、符號、甚至是表情符號 (Emoji)。

關鍵特性:

  • 大小固定: Rust 的 char 類型占用 4 個字節 (32 位) 的內存空間。這足以表示所有的 Unicode 標量值。
  • 字面量: 使用單引號 (') 包裹。
  • 與字符串的區別: char 表示單個字符,而 Rust 的字符串 (String, &str) 是 UTF-8 編碼的字節序列,一個字符在 UTF-8 中可能占用 1 到 4 個字節。
fn main() {let c = 'z';let z = '?'; // 一個數學符號let heart_eyed_cat = '😻'; // 一個表情符號let pi = 'π'; // 希臘字母 Piprintln!("字符 c: {}", c);println!("字符 z: {}", z);println!("字符 cat: {}", heart_eyed_cat);println!("字符 pi: {}", pi);// char 的大小總是 4 字節println!("Size of char: {} bytes", std::mem::size_of::<char>()); // 輸出: 4// 對比字符串中字符的 UTF-8 字節長度let s = "😻"; // 這是一個 &str (字符串切片)println!("字符串 \"😻\" 的字節長度 (UTF-8): {}", s.len()); // 輸出: 4 (因為它在 UTF-8 中需要 4 個字節)// 但它只包含一個 charprintln!("字符串 \"😻\" 包含的 char 數量: {}", s.chars().count()); // 輸出: 1// 可以對 char 進行一些操作assert!(pi.is_alphabetic()); // 檢查是否是字母類字符assert!(heart_eyed_cat.is_emoji()); // 需要引入 `unicode-segmentation` 等庫來做更復雜的判斷,標準庫能力有限println!("'A' 的小寫形式: {}", 'A'.to_lowercase().next().unwrap()); // 輸出: a
}

Rust 對 char 的定義(基于 Unicode 標量值并固定為 4 字節)體現了其面向全球化和現代文本處理的設計思想。它避免了許多其他語言中處理非 ASCII 字符時可能遇到的編碼問題和歧義。

五、類型注解與推斷再探

雖然 Rust 的類型推斷很強大,可以推斷出大部分標量類型,但在某些情況下,顯式類型注解 (Type Annotation) 是必需的或推薦的:

  1. 消除歧義: 當一個字面量可以被解釋為多種類型時,例如 parse 方法需要知道目標類型。
    let guess: u32 = "42".parse().expect("Not a number!"); // 必須告訴 parse 我們想要 u32
    
  2. 常量和靜態變量: conststatic 聲明必須顯式標注類型。
  3. 函數簽名: 函數的參數和返回值類型必須明確標注。
  4. 復雜類型或提高可讀性: 對于復雜的復合類型,或者為了讓代碼意圖更清晰,有時即使編譯器能推斷,也建議加上類型注解。

對于標量類型,通常只有在默認類型(如 i32, f64)不適用或存在歧義時,才需要顯式注解。

總結:堅實的基礎,精確的表達

今天我們深入了解了 Rust 的四大標量類型:

  • 整數: 提供了多種位寬和有/無符號選項,強調 usize 用于索引,并對整數溢出有明確、安全的處理機制(debug panic, release wrap, explicit methods)。
  • 浮點數: 基于 IEEE 754 標準的 f32f64(默認),需注意精度問題和比較陷阱。
  • 布爾值: 簡單的 bool 類型 (true/false),強類型系統防止與整數混用。
  • 字符: char 代表 4 字節的 Unicode 標量值,支持全球字符集。

Rust 對這些基礎類型的精確定義和嚴格的類型檢查,是其可靠性的重要來源。它鼓勵開發者思考數據的具體表示、范圍和潛在問題(如溢出、精度),并通過編譯器提供強有力的保障。這些看似基礎的知識,構成了我們未來構建更復雜、更健壯程序所依賴的堅實地基。

FAQ:關于標量類型的常見疑問

  • Q1: 如何選擇合適的整數類型? i32 夠用嗎?
    • A: 如果不確定,i32 是個不錯的起點,性能好且范圍適中。但最好根據數據的實際范圍選擇最小的能容納的類型,可以節省內存。如果明確知道不需要負數,使用無符號類型 (u8, u16 等)。對于集合索引和內存大小相關的值,必須使用 usize
  • Q2: 為什么 f64 是默認浮點類型,而不是更省內存的 f32
    • A: 現代 64 位 CPU 處理 f64 的速度通常不亞于 f32,而 f64 的精度更高,能減少累積誤差。因此,Rust 選擇了精度優先作為默認行為。
  • Q3: Rust 的 char 和 C/C++ 的 char 有什么不同?
    • A: C/C++ 的 char 通常是 1 字節,主要表示 ASCII 字符或字節值。Rust 的 char 是 4 字節,設計用來表示任意 Unicode 標量值,更能適應現代多語言文本處理的需求。Rust 中的 u8 類型更接近 C/C++ char 表示字節的概念。
  • Q4: usizeu64 在 64 位系統上大小一樣,可以混用嗎?
    • A: 雖然它們在 64 位系統上大小相同,但語義不同。usize 的語義是“足夠大以容納內存中任何對象的指針或索引”,其大小隨架構變化。u64 則始終是 64 位無符號整數。代碼中應根據語義選擇:用于索引、長度、大小的,用 usize;用于表示明確需要 64 位存儲的數字(與架構無關)時,用 u64。不能直接混用,需要顯式轉換 (as)。

下一篇預告:組合的力量——復合類型初探

掌握了構成數據的“原子”(標量類型),下一步我們將學習如何將它們組合起來,構建更復雜的數據結構。

下一篇:【數據基石·下】復合類型:元組 (Tuple) 與數組 (Array) 的定長世界。 我們將探索如何將不同或相同類型的值組合成固定的集合。敬請期待!

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

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

相關文章

消息中間件RabbitMQ:簡要介紹及其Windows安裝流程

一、簡要介紹 定義&#xff1a;RabbitMQ 是一個開源消息中間件&#xff0c;用于實現消息隊列和異步通信。 場景&#xff1a;適用于分布式系統、異步任務處理、消息解耦、負載均衡等場景。 比喻&#xff1a;RabbitMQ 就像是快遞公司&#xff0c;負責在不同系統間安全快速地傳遞…

Docker概念詳解

文章目錄 一、Docker&#xff1a;容器化應用的基石1.1 環境1.2 Docker 是什么1.3 Docker鏡像1.3.1 基礎鏡像(Base Image)1.3.2 Dockerfile1.3.3 容器鏡像&#xff08;Container Image&#xff09; 1.4 Registry1.5 容器1.6 Docker VS 虛擬機 二、Docker 的架構原理2.1 C/S軟件架…

linux查看及修改用戶過期時間

修改用戶有效期 密碼到期時間 sudo chage -E 2025-12-31 username sudo chage -M 180 username sudo chage -d $(date %F) username 查詢用戶密碼到期時間 for user in $(cat /etc/passwd |cut -d: -f1); do echo $user; chage -l $user | grep "Password expires"; …

CGAL 計算直線之間的距離(3D)

文章目錄 一、簡介二、實現代碼三、實現效果一、簡介 這里的計算思路很簡單: 1、首先將兩個三維直線均平移至過原點處,這里兩條直線可以構成一個平面normal。 2、如果兩個直線平行,那么兩條直線之間的距離就轉換為直線上一點到另一直線的距離。 3、如果兩個直線不平行,則可…

<項目代碼>YOLO小船識別<目標檢測>

項目代碼下載鏈接 YOLOv8是一種單階段&#xff08;one-stage&#xff09;檢測算法&#xff0c;它將目標檢測問題轉化為一個回歸問題&#xff0c;能夠在一次前向傳播過程中同時完成目標的分類和定位任務。相較于兩階段檢測算法&#xff08;如Faster R-CNN&#xff09;&#xff0…

基于RK3588+FPGA+AI YOLO全國產化的無人船目標檢測系統(二)平臺設計

基于項目需求確定國產 AI 平臺的總體架構設計&#xff0c;完成硬件單元的選擇和搭建以及開發工具鏈的配置工作。 4.1 國產 AI 平臺總體架構 本文設計了一套靈活高效的國產 AI 平臺總體架構&#xff0c;設計方法是在嵌入式平 臺上使用串行總線&#xff08; Peripheral Co…

Typescript中的泛型約束extends keyof

概要 本文主要分享Typescript中泛型約束的使用方法。在開發過程中&#xff0c;通過使用該方法&#xff0c;可以在編譯階段&#xff0c;幫助我們查找到一些潛在的空值引用錯誤。 代碼和實現 我們預先定義了IUser接口&#xff0c;接口包括了id&#xff0c;姓名&#xff0c;性別…

C++ 2025 展望:現代編程需求與新興技術驅動下的變革

C 作為一門成熟的語言&#xff0c;在多個領域&#xff08;嵌入式系統、高性能計算、圖形渲染、游戲開發等&#xff09;依舊占據重要地位。在 2024 年&#xff0c;C 開發繼續在許多傳統領域保持強勁的勢頭&#xff0c;同時也面臨著新的挑戰與發展方向。展望 2025 年&#xff0c;…

包管理工具有哪些?主流軟件分享

常見的包管理工具主要有&#xff1a;npm、Yarn、pnpm、Composer、Maven、pip、Conda 等&#xff0c;其中 npm 是目前全球使用最廣泛的JavaScript包管理工具&#xff0c;以豐富的生態、便捷的使用體驗以及強大的社區支持聞名。npm具備依賴管理、版本控制、腳本執行等強大功能&am…

2025年世界職業院校技能大賽實施方案(意見稿)

為貫徹落實《教育強國建設規劃綱要&#xff08;2024—2035年&#xff09;》&#xff0c;進一步提升世界職業院校技能大賽&#xff08;以下簡稱“大賽”&#xff09;內涵質量&#xff0c;發揮大賽引領作用&#xff0c;提升高技能人才培養質量&#xff0c;服務現代職業教育體系建…

Redis 慢查詢分析與優化

Redis 慢查詢分析與優化 參考書籍 &#xff1a; https://weread.qq.com/web/reader/d5432be0813ab98b6g0133f5kd8232f00235d82c8d161fb2 以下從配置參數、耗時細分、分析工具、優化策略四個維度深入解析 Redis 慢查詢問題&#xff0c;結合實戰調優建議&#xff0c;幫助開發者…

AI之pdf解析:Tesseract、PaddleOCR、RapidPaddle(可能為 RapidOCR)和 plumberpdf 的對比分析及使用建議

目錄標題 Tesseract、PaddleOCR、RapidPaddle&#xff08;可能為 RapidOCR&#xff09;和 plumberpdf 的對比分析1. Tesseract類型: 開源 OCR 引擎特點:缺點:適用場景: 2. PaddleOCR (推薦)類型:特點:缺點:適用場景: 復雜版式文檔、多語言混合文本、需要高精度識別的場景&#…

算法 | 成長優化算法(Growth Optimizer,GO)原理,公式,應用,算法改進研究綜述,matlab代碼

===================================================== github:https://github.com/MichaelBeechan CSDN:https://blog.csdn.net/u011344545 ===================================================== 成長優化算法 一、算法原理二、核心公式三、應用領域四、算法改進研究五…

網絡原理(TCP協議—協議格式,性質(上),狀態)

目錄 1.TCP協議段格式。 2.TCP協議傳輸時候的性質。 2.1確認應答。 2.2超時重傳。 2.3連接管理。 2.3.1 三次握手。 2.3.2四次揮手。 3.TCP常見的狀態。 1.TCP協議段格式。 TCP協議段是由首部和數據兩部分構成的。首部包含了TCP通信所需要的各種控制信息&#xff0c;而…

XAML 標記擴展

# XAML 標記擴展詳解 標記擴展(Markup Extensions)是XAML中一種特殊的語法結構&#xff0c;允許在XAML屬性中嵌入動態值或引用&#xff0c;而不是簡單的靜態值。它們使用花括號{}作為標識&#xff0c;是XAML強大功能的核心組成部分。 ## 基本語法結構 所有標記擴展都遵循以下…

DeepSeek+Cursor+Devbox+Sealos項目實戰

黑馬程序員DeepSeekCursorDevboxSealos帶你零代碼搞定實戰項目開發部署視頻教程&#xff0c;基于AI完成項目的設計、開發、測試、聯調、部署全流程 原視頻地址視頻選的項目非常基礎&#xff0c;基本就是過了個web開發流程&#xff0c;但我在實際跟著操作時&#xff0c;ai依然會…

Ethan獨立開發產品日報 | 2025-04-20

1. Checklist GG 基于人工智能的清單管理工具 checklist.gg是一個基于人工智能的清單管理工具&#xff0c;旨在幫助組織確保每次都能正確完成任務。 關鍵詞&#xff1a;AI驅動, 檢查清單, 管理工具, 任務管理, 效率提升, 組織管理, 工作流程, 自動化工具, 清單管理, 協作工具…

第十四屆藍橋杯 2023 C/C++組 冶煉金屬

目錄 題目&#xff1a; 題目描述&#xff1a; 題目鏈接&#xff1a; 思路&#xff1a; 核心思路&#xff1a; 思路詳解&#xff1a; 代碼&#xff1a; 代碼詳解&#xff1a; 題目&#xff1a; 題目描述&#xff1a; 題目鏈接&#xff1a; 藍橋云課 冶煉金屬 洛谷 P92…

【數字圖像處理】彩色圖像處理(1)

研究彩色圖像處理的原因 1&#xff1a;利用顏色信息&#xff0c;可以簡化目標物的區分&#xff0c;以及從場景中提取出目標物 2&#xff1a;人眼對顏色非常敏感&#xff0c;可以分辨出來幾千種顏色色調和亮度&#xff0c;卻只能分別出幾十種灰度 彩色圖像分類 偽彩色圖像處理&…

pytest自動化中關于使用fixture是否影響用例的獨立性

第一個問題&#xff1a;難道使用fixture 會影響用例獨立嗎&#xff1f; ? 簡單回答&#xff1a; 使用 fixture ≠ 不獨立。 只要你的 fixture 是每次測試都能自己運行、自己產生數據的&#xff0c;那么測試用例依然是“邏輯獨立”的。 ? 怎么判斷 fixture 是否影響獨立性&a…