Created
March 4, 2026 15:06
-
-
Save jiayun/05f72975b9fa7811db2dd8e6bebe0b5b to your computer and use it in GitHub Desktop.
Ch25 Cargo and Ecosystem — 完整範例
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // === Feature Flag 與條件編譯 === | |
| // 使用 cfg attribute 根據條件選擇不同的實作 | |
| // 實際專案中,feature flag 定義在 Cargo.toml 的 [features] 區段 | |
| // 這裡用 cfg(debug_assertions) 和 cfg(target_os) 來示範相同的概念 | |
| /// 根據編譯模式回傳不同的日誌等級 | |
| fn log_level() -> &'static str { | |
| // debug_assertions 在 `cargo run` (debug) 時為 true | |
| // 在 `cargo run --release` 時為 false | |
| if cfg!(debug_assertions) { | |
| "DEBUG" | |
| } else { | |
| "RELEASE" | |
| } | |
| } | |
| /// 使用 #[cfg] attribute 進行條件編譯 | |
| #[cfg(target_os = "macos")] | |
| fn platform_info() -> &'static str { | |
| "Running on macOS" | |
| } | |
| #[cfg(target_os = "linux")] | |
| fn platform_info() -> &'static str { | |
| "Running on Linux" | |
| } | |
| #[cfg(target_os = "windows")] | |
| fn platform_info() -> &'static str { | |
| "Running on Windows" | |
| } | |
| #[cfg(not(any(target_os = "macos", target_os = "linux", target_os = "windows")))] | |
| fn platform_info() -> &'static str { | |
| "Running on other platform" | |
| } | |
| // === Build 時期資訊 === | |
| /// 展示 Cargo 在編譯時注入的環境變數 | |
| fn show_build_info() { | |
| // Cargo 自動設定的環境變數,可用 env!() 在編譯時讀取 | |
| let pkg_name = env!("CARGO_PKG_NAME"); | |
| let pkg_version = env!("CARGO_PKG_VERSION"); | |
| let manifest_dir = env!("CARGO_MANIFEST_DIR"); | |
| println!("套件名稱:{pkg_name}"); | |
| println!("套件版本:{pkg_version}"); | |
| println!("Manifest 路徑:{manifest_dir}"); | |
| } | |
| // === 模擬 Feature Flag 切換的設計模式 === | |
| /// 模擬一個根據 feature 切換序列化格式的函式 | |
| /// 實際專案中會用 #[cfg(feature = "json")] 等 attribute | |
| fn serialize_data(data: &str) -> String { | |
| // 這裡用 cfg!(debug_assertions) 模擬 feature flag 的選擇邏輯 | |
| if cfg!(debug_assertions) { | |
| // 模擬「verbose」模式的輸出 | |
| format!("{{\"data\": \"{data}\", \"mode\": \"debug\"}}") | |
| } else { | |
| // 模擬「compact」模式的輸出 | |
| format!("{{\"{data}\"}}") | |
| } | |
| } | |
| // === 常用 Patterns === | |
| /// 展示版本資訊的常見模式 | |
| fn version_string() -> String { | |
| format!( | |
| "{} v{} ({})", | |
| env!("CARGO_PKG_NAME"), | |
| env!("CARGO_PKG_VERSION"), | |
| if cfg!(debug_assertions) { | |
| "debug" | |
| } else { | |
| "release" | |
| } | |
| ) | |
| } | |
| /// 模擬根據目標架構選擇不同實作 | |
| fn pointer_width() -> &'static str { | |
| if cfg!(target_pointer_width = "64") { | |
| "64-bit platform" | |
| } else if cfg!(target_pointer_width = "32") { | |
| "32-bit platform" | |
| } else { | |
| "other platform" | |
| } | |
| } | |
| fn main() { | |
| println!("=== Ch25:Cargo 進階與生態系 ===\n"); | |
| // --- Feature Flag 與條件編譯 --- | |
| println!("--- 條件編譯 ---"); | |
| println!("目前日誌等級:{}", log_level()); | |
| println!("平台資訊:{}", platform_info()); | |
| println!("架構:{}", pointer_width()); | |
| println!(); | |
| // --- Build 時期資訊 --- | |
| println!("--- Build 資訊 ---"); | |
| show_build_info(); | |
| println!(); | |
| // --- 模擬 Feature Flag --- | |
| println!("--- 模擬 Feature Flag ---"); | |
| let serialized = serialize_data("hello"); | |
| println!("序列化結果:{serialized}"); | |
| println!(); | |
| // --- 版本字串 --- | |
| println!("--- 版本資訊 ---"); | |
| println!("{}", version_string()); | |
| println!(); | |
| // --- cfg! 與 #[cfg] 的差異 --- | |
| println!("--- cfg! 巨集 vs #[cfg] attribute ---"); | |
| println!("cfg! 巨集:在執行期作為布林值使用(但值在編譯時決定)"); | |
| println!(" cfg!(debug_assertions) = {}", cfg!(debug_assertions)); | |
| println!("#[cfg(...)]:在編譯時決定整個項目是否包含在最終二進位檔中"); | |
| println!(" platform_info() 只有對應平台的版本會被編譯"); | |
| println!(); | |
| // --- 環境變數全覽 --- | |
| println!("--- Cargo 環境變數 ---"); | |
| println!("CARGO_PKG_NAME = {}", env!("CARGO_PKG_NAME")); | |
| println!("CARGO_PKG_VERSION = {}", env!("CARGO_PKG_VERSION")); | |
| println!( | |
| "CARGO_PKG_VERSION_MAJOR = {}", | |
| env!("CARGO_PKG_VERSION_MAJOR") | |
| ); | |
| println!( | |
| "CARGO_PKG_VERSION_MINOR = {}", | |
| env!("CARGO_PKG_VERSION_MINOR") | |
| ); | |
| println!( | |
| "CARGO_PKG_VERSION_PATCH = {}", | |
| env!("CARGO_PKG_VERSION_PATCH") | |
| ); | |
| println!(); | |
| // --- 常見 crate 介紹的概念範例 --- | |
| println!("--- Rust 生態系常用 crate ---"); | |
| let crates = [ | |
| ( | |
| "serde", | |
| "序列化/反序列化框架", | |
| "serde = { version = \"1\", features = [\"derive\"] }", | |
| ), | |
| ( | |
| "tokio", | |
| "非同步執行時期", | |
| "tokio = { version = \"1\", features = [\"full\"] }", | |
| ), | |
| ( | |
| "clap", | |
| "命令列引數解析", | |
| "clap = { version = \"4\", features = [\"derive\"] }", | |
| ), | |
| ("tracing", "結構化日誌與追蹤", "tracing = \"0.1\""), | |
| ("anyhow", "應用程式錯誤處理", "anyhow = \"1\""), | |
| ("thiserror", "函式庫錯誤型別定義", "thiserror = \"2\""), | |
| ( | |
| "reqwest", | |
| "HTTP 客戶端", | |
| "reqwest = { version = \"0.12\", features = [\"json\"] }", | |
| ), | |
| ("rand", "亂數產生", "rand = \"0.9\""), | |
| ]; | |
| for (name, desc, dep) in &crates { | |
| println!(" {name:<12} — {desc}"); | |
| println!(" {:<12} {dep}", ""); | |
| } | |
| println!("\n=== 程式結束 ==="); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment