Skip to content

Instantly share code, notes, and snippets.

@jiayun
Created March 4, 2026 15:06
Show Gist options
  • Select an option

  • Save jiayun/05f72975b9fa7811db2dd8e6bebe0b5b to your computer and use it in GitHub Desktop.

Select an option

Save jiayun/05f72975b9fa7811db2dd8e6bebe0b5b to your computer and use it in GitHub Desktop.
Ch25 Cargo and Ecosystem — 完整範例
// === 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