[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M7BFH9DA443RJ4CM2N06TZXC":3,"skill-same:01M7BFH9DA443RJ4CM2N06TZXC":48},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":18,"publishedAt":19,"linkOnly":20,"markdownContent":21,"markdownBody":22,"frontMatter":23,"refName":25,"commitSha":26,"skillDirectory":27,"forksCount":28,"repositoryHtmlUrl":29,"repositoryHomepageUrl":30,"ownerHtmlUrl":31,"ownerBlogUrl":6,"ownerDescription":32,"updatedAt":33,"install":34,"resources":47},"01M7BFH9DA443RJ4CM2N06TZXC","rust-patterns",null,"地道的Rust模式、所有权、错误处理、特质、并发，以及构建安全、高性能应用程序的最佳实践。","YYC-Cube\u002FYYC3-Knowledge-Base","YYC-Cube","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F235006543?v=4","01M79J2PH4SWD2X0825X6PN748","yyc3","01M79J2PHVK3F6ZBYT8K2SCZCW",1,"MIT","https:\u002F\u002Fgithub.com\u002FYYC-Cube\u002FYYC3-Knowledge-Base\u002Fblob\u002Fmain\u002FYYC3-AI-应用工具\u002FYYC3-AI-应用工具-Everything-claude-code\u002Fdocs\u002Fzh-CN\u002Fskills\u002Frust-patterns\u002FSKILL.md",[],[],"2026-11-15 14:19:17",false,"---\nname: rust-patterns\ndescription: 地道的Rust模式、所有权、错误处理、特质、并发，以及构建安全、高性能应用程序的最佳实践。\norigin: ECC\n---\n\n# Rust 开发模式\n\n构建安全、高性能且可维护应用程序的惯用 Rust 模式和最佳实践。\n\n## 何时使用\n\n* 编写新的 Rust 代码时\n* 评审 Rust 代码时\n* 重构现有 Rust 代码时\n* 设计 crate 结构和模块布局时\n\n## 工作原理\n\n此技能在六个关键领域强制执行惯用的 Rust 约定：所有权和借用，用于在编译时防止数据竞争；`Result`\u002F`?` 错误传播，库使用 `thiserror` 而应用程序使用 `anyhow`；枚举和穷尽模式匹配，使非法状态无法表示；用于零成本抽象的 trait 和泛型；通过 `Arc\u003CMutex\u003CT>>`、通道和 async\u002Fawait 实现的安全并发；以及按领域组织的最小化 `pub` 接口。\n\n## 核心原则\n\n### 1. 所有权和借用\n\nRust 的所有权系统在编译时防止数据竞争和内存错误。\n\n```rust\n\u002F\u002F Good: Pass references when you don't need ownership\nfn process(data: &[u8]) -> usize {\n    data.len()\n}\n\n\u002F\u002F Good: Take ownership only when you need to store or consume\nfn store(data: Vec\u003Cu8>) -> Record {\n    Record { payload: data }\n}\n\n\u002F\u002F Bad: Cloning unnecessarily to avoid borrow checker\nfn process_bad(data: &Vec\u003Cu8>) -> usize {\n    let cloned = data.clone(); \u002F\u002F Wasteful — just borrow\n    cloned.len()\n}\n```\n\n### 使用 `Cow` 实现灵活的所有权\n\n```rust\nuse std::borrow::Cow;\n\nfn normalize(input: &str) -> Cow\u003C'_, str> {\n    if input.contains(' ') {\n        Cow::Owned(input.replace(' ', \"_\"))\n    } else {\n        Cow::Borrowed(input) \u002F\u002F Zero-cost when no mutation needed\n    }\n}\n```\n\n## 错误处理\n\n### 使用 `Result` 和 `?` —— 切勿在生产环境中使用 `unwrap()`\n\n```rust\n\u002F\u002F Good: Propagate errors with context\nuse anyhow::{Context, Result};\n\nfn load_config(path: &str) -> Result\u003CConfig> {\n    let content = std::fs::read_to_string(path)\n        .with_context(|| format!(\"failed to read config from {path}\"))?;\n    let config: Config = toml::from_str(&content)\n        .with_context(|| format!(\"failed to parse config from {path}\"))?;\n    Ok(config)\n}\n\n\u002F\u002F Bad: Panics on error\nfn load_config_bad(path: &str) -> Config {\n    let content = std::fs::read_to_string(path).unwrap(); \u002F\u002F Panics!\n    toml::from_str(&content).unwrap()\n}\n```\n\n### 库错误使用 `thiserror`，应用程序错误使用 `anyhow`\n\n```rust\n\u002F\u002F Library code: structured, typed errors\nuse thiserror::Error;\n\n#[derive(Debug, Error)]\npub enum StorageError {\n    #[error(\"record not found: {id}\")]\n    NotFound { id: String },\n    #[error(\"connection failed\")]\n    Connection(#[from] std::io::Error),\n    #[error(\"invalid data: {0}\")]\n    InvalidData(String),\n}\n\n\u002F\u002F Application code: flexible error handling\nuse anyhow::{bail, Result};\n\nfn run() -> Result\u003C()> {\n    let config = load_config(\"app.toml\")?;\n    if config.workers == 0 {\n        bail!(\"worker count must be > 0\");\n    }\n    Ok(())\n}\n```\n\n### 优先使用 `Option` 组合子而非嵌套匹配\n\n```rust\n\u002F\u002F Good: Combinator chain\nfn find_user_email(users: &[User], id: u64) -> Option\u003CString> {\n    users.iter()\n        .find(|u| u.id == id)\n        .map(|u| u.email.clone())\n}\n\n\u002F\u002F Bad: Deeply nested matching\nfn find_user_email_bad(users: &[User], id: u64) -> Option\u003CString> {\n    match users.iter().find(|u| u.id == id) {\n        Some(user) => match &user.email {\n            email => Some(email.clone()),\n        },\n        None => None,\n    }\n}\n```\n\n## 枚举和模式匹配\n\n### 将状态建模为枚举\n\n```rust\n\u002F\u002F Good: Impossible states are unrepresentable\nenum ConnectionState {\n    Disconnected,\n    Connecting { attempt: u32 },\n    Connected { session_id: String },\n    Failed { reason: String, retries: u32 },\n}\n\nfn handle(state: &ConnectionState) {\n    match state {\n        ConnectionState::Disconnected => connect(),\n        ConnectionState::Connecting { attempt } if *attempt > 3 => abort(),\n        ConnectionState::Connecting { .. } => wait(),\n        ConnectionState::Connected { session_id } => use_session(session_id),\n        ConnectionState::Failed { retries, .. } if *retries \u003C 5 => retry(),\n        ConnectionState::Failed { reason, .. } => log_failure(reason),\n    }\n}\n```\n\n### 穷尽匹配 —— 业务逻辑中不使用通配符\n\n```rust\n\u002F\u002F Good: Handle every variant explicitly\nmatch command {\n    Command::Start => start_service(),\n    Command::Stop => stop_service(),\n    Command::Restart => restart_service(),\n    \u002F\u002F Adding a new variant forces handling here\n}\n\n\u002F\u002F Bad: Wildcard hides new variants\nmatch command {\n    Command::Start => start_service(),\n    _ => {} \u002F\u002F Silently ignores Stop, Restart, and future variants\n}\n```\n\n## Trait 和泛型\n\n### 接受泛型，返回具体类型\n\n```rust\n\u002F\u002F Good: Generic input, concrete output\nfn read_all(reader: &mut impl Read) -> std::io::Result\u003CVec\u003Cu8>> {\n    let mut buf = Vec::new();\n    reader.read_to_end(&mut buf)?;\n    Ok(buf)\n}\n\n\u002F\u002F Good: Trait bounds for multiple constraints\nfn process\u003CT: Display + Send + 'static>(item: T) -> String {\n    format!(\"processed: {item}\")\n}\n```\n\n### 使用 Trait 对象进行动态分发\n\n```rust\n\u002F\u002F Use when you need heterogeneous collections or plugin systems\ntrait Handler: Send + Sync {\n    fn handle(&self, request: &Request) -> Response;\n}\n\nstruct Router {\n    handlers: Vec\u003CBox\u003Cdyn Handler>>,\n}\n\n\u002F\u002F Use generics when you need performance (monomorphization)\nfn fast_process\u003CH: Handler>(handler: &H, request: &Request) -> Response {\n    handler.handle(request)\n}\n```\n\n### 使用 Newtype 模式确保类型安全\n\n```rust\n\u002F\u002F Good: Distinct types prevent mixing up arguments\nstruct UserId(u64);\nstruct OrderId(u64);\n\nfn get_order(user: UserId, order: OrderId) -> Result\u003COrder> {\n    \u002F\u002F Can't accidentally swap user and order IDs\n    todo!()\n}\n\n\u002F\u002F Bad: Easy to swap arguments\nfn get_order_bad(user_id: u64, order_id: u64) -> Result\u003COrder> {\n    todo!()\n}\n```\n\n## 结构体和数据建模\n\n### 使用构建器模式进行复杂构造\n\n```rust\nstruct ServerConfig {\n    host: String,\n    port: u16,\n    max_connections: usize,\n}\n\nimpl ServerConfig {\n    fn builder(host: impl Into\u003CString>, port: u16) -> ServerConfigBuilder {\n        ServerConfigBuilder { host: host.into(), port, max_connections: 100 }\n    }\n}\n\nstruct ServerConfigBuilder { host: String, port: u16, max_connections: usize }\n\nimpl ServerConfigBuilder {\n    fn max_connections(mut self, n: usize) -> Self { self.max_connections = n; self }\n    fn build(self) -> ServerConfig {\n        ServerConfig { host: self.host, port: self.port, max_connections: self.max_connections }\n    }\n}\n\n\u002F\u002F Usage: ServerConfig::builder(\"localhost\", 8080).max_connections(200).build()\n```\n\n## 迭代器和闭包\n\n### 优先使用迭代器链而非手动循环\n\n```rust\n\u002F\u002F Good: Declarative, lazy, composable\nlet active_emails: Vec\u003CString> = users.iter()\n    .filter(|u| u.is_active)\n    .map(|u| u.email.clone())\n    .collect();\n\n\u002F\u002F Bad: Imperative accumulation\nlet mut active_emails = Vec::new();\nfor user in &users {\n    if user.is_active {\n        active_emails.push(user.email.clone());\n    }\n}\n```\n\n### 使用带有类型注解的 `collect()`\n\n```rust\n\u002F\u002F Collect into different types\nlet names: Vec\u003C_> = items.iter().map(|i| &i.name).collect();\nlet lookup: HashMap\u003C_, _> = items.iter().map(|i| (i.id, i)).collect();\nlet combined: String = parts.iter().copied().collect();\n\n\u002F\u002F Collect Results — short-circuits on first error\nlet parsed: Result\u003CVec\u003Ci32>, _> = strings.iter().map(|s| s.parse()).collect();\n```\n\n## 并发\n\n### 使用 `Arc\u003CMutex\u003CT>>` 处理共享可变状态\n\n```rust\nuse std::sync::{Arc, Mutex};\n\nlet counter = Arc::new(Mutex::new(0));\nlet handles: Vec\u003C_> = (0..10).map(|_| {\n    let counter = Arc::clone(&counter);\n    std::thread::spawn(move || {\n        let mut num = counter.lock().expect(\"mutex poisoned\");\n        *num += 1;\n    })\n}).collect();\n\nfor handle in handles {\n    handle.join().expect(\"worker thread panicked\");\n}\n```\n\n### 使用通道进行消息传递\n\n```rust\nuse std::sync::mpsc;\n\nlet (tx, rx) = mpsc::sync_channel(16); \u002F\u002F Bounded channel with backpressure\n\nfor i in 0..5 {\n    let tx = tx.clone();\n    std::thread::spawn(move || {\n        tx.send(format!(\"message {i}\")).expect(\"receiver disconnected\");\n    });\n}\ndrop(tx); \u002F\u002F Close sender so rx iterator terminates\n\nfor msg in rx {\n    println!(\"{msg}\");\n}\n```\n\n### 使用 Tokio 进行异步编程\n\n```rust\nuse tokio::time::Duration;\n\nasync fn fetch_with_timeout(url: &str) -> Result\u003CString> {\n    let response = tokio::time::timeout(\n        Duration::from_secs(5),\n        reqwest::get(url),\n    )\n    .await\n    .context(\"request timed out\")?\n    .context(\"request failed\")?;\n\n    response.text().await.context(\"failed to read body\")\n}\n\n\u002F\u002F Spawn concurrent tasks\nasync fn fetch_all(urls: Vec\u003CString>) -> Vec\u003CResult\u003CString>> {\n    let handles: Vec\u003C_> = urls.into_iter()\n        .map(|url| tokio::spawn(async move {\n            fetch_with_timeout(&url).await\n        }))\n        .collect();\n\n    let mut results = Vec::with_capacity(handles.len());\n    for handle in handles {\n        results.push(handle.await.unwrap_or_else(|e| panic!(\"spawned task panicked: {e}\")));\n    }\n    results\n}\n```\n\n## 不安全代码\n\n### 何时可以使用 Unsafe\n\n```rust\n\u002F\u002F Acceptable: FFI boundary with documented invariants (Rust 2024+)\n\u002F\u002F\u002F # Safety\n\u002F\u002F\u002F `ptr` must be a valid, aligned pointer to an initialized `Widget`.\nunsafe fn widget_from_raw\u003C'a>(ptr: *const Widget) -> &'a Widget {\n    \u002F\u002F SAFETY: caller guarantees ptr is valid and aligned\n    unsafe { &*ptr }\n}\n\n\u002F\u002F Acceptable: Performance-critical path with proof of correctness\n\u002F\u002F SAFETY: index is always \u003C len due to the loop bound\nunsafe { slice.get_unchecked(index) }\n```\n\n### 何时不可以使用 Unsafe\n\n```rust\n\u002F\u002F Bad: Using unsafe to bypass borrow checker\n\u002F\u002F Bad: Using unsafe for convenience\n\u002F\u002F Bad: Using unsafe without a Safety comment\n\u002F\u002F Bad: Transmuting between unrelated types\n```\n\n## 模块系统和 Crate 结构\n\n### 按领域组织，而非按类型\n\n```text\nmy_app\u002F\n├── src\u002F\n│   ├── main.rs\n│   ├── lib.rs\n│   ├── auth\u002F          # 领域模块\n│   │   ├── mod.rs\n│   │   ├── token.rs\n│   │   └── middleware.rs\n│   ├── orders\u002F        # 领域模块\n│   │   ├── mod.rs\n│   │   ├── model.rs\n│   │   └── service.rs\n│   └── db\u002F            # 基础设施\n│       ├── mod.rs\n│       └── pool.rs\n├── tests\u002F             # 集成测试\n├── benches\u002F           # 基准测试\n└── Cargo.toml\n```\n\n### 可见性 —— 最小化暴露\n\n```rust\n\u002F\u002F Good: pub(crate) for internal sharing\npub(crate) fn validate_input(input: &str) -> bool {\n    !input.is_empty()\n}\n\n\u002F\u002F Good: Re-export public API from lib.rs\npub mod auth;\npub use auth::AuthMiddleware;\n\n\u002F\u002F Bad: Making everything pub\npub fn internal_helper() {} \u002F\u002F Should be pub(crate) or private\n```\n\n## 工具集成\n\n### 基本命令\n\n```bash\n# Build and check\ncargo build\ncargo check              # Fast type checking without codegen\ncargo clippy             # Lints and suggestions\ncargo fmt                # Format code\n\n# Testing\ncargo test\ncargo test -- --nocapture    # Show println output\ncargo test --lib             # Unit tests only\ncargo test --test integration # Integration tests only\n\n# Dependencies\ncargo audit              # Security audit\ncargo tree               # Dependency tree\ncargo update             # Update dependencies\n\n# Performance\ncargo bench              # Run benchmarks\n```\n\n## 快速参考：Rust 惯用法\n\n| 惯用法 | 描述 |\n|-------|-------------|\n| 借用，而非克隆 | 传递 `&T`，除非需要所有权，否则不要克隆 |\n| 使非法状态无法表示 | 使用枚举仅对有效状态进行建模 |\n| `?` 优于 `unwrap()` | 传播错误，切勿在库\u002F生产代码中恐慌 |\n| 解析，而非验证 | 在边界处将非结构化数据转换为类型化结构体 |\n| Newtype 用于类型安全 | 将基本类型包装在 newtype 中以防止参数错位 |\n| 优先使用迭代器而非循环 | 声明式链更清晰且通常更快 |\n| 对 Result 使用 `#[must_use]` | 确保调用者处理返回值 |\n| 使用 `Cow` 实现灵活的所有权 | 当借用足够时避免分配 |\n| 穷尽匹配 | 业务关键枚举不使用通配符 `_` |\n| 最小化 `pub` 接口 | 内部 API 使用 `pub(crate)` |\n\n## 应避免的反模式\n\n```rust\n\u002F\u002F Bad: .unwrap() in production code\nlet value = map.get(\"key\").unwrap();\n\n\u002F\u002F Bad: .clone() to satisfy borrow checker without understanding why\nlet data = expensive_data.clone();\nprocess(&original, &data);\n\n\u002F\u002F Bad: Using String when &str suffices\nfn greet(name: String) { \u002F* should be &str *\u002F }\n\n\u002F\u002F Bad: Box\u003Cdyn Error> in libraries (use thiserror instead)\nfn parse(input: &str) -> Result\u003CData, Box\u003Cdyn std::error::Error>> { todo!() }\n\n\u002F\u002F Bad: Ignoring must_use warnings\nlet _ = validate(input); \u002F\u002F Silently discarding a Result\n\n\u002F\u002F Bad: Blocking in async context\nasync fn bad_async() {\n    std::thread::sleep(Duration::from_secs(1)); \u002F\u002F Blocks the executor!\n    \u002F\u002F Use: tokio::time::sleep(Duration::from_secs(1)).await;\n}\n```\n\n**请记住**：如果它能编译，那它很可能是正确的 —— 但前提是你要避免 `unwrap()`，最小化 `unsafe`，并让类型系统为你工作。\n","# Rust 开发模式\n\n构建安全、高性能且可维护应用程序的惯用 Rust 模式和最佳实践。\n\n## 何时使用\n\n* 编写新的 Rust 代码时\n* 评审 Rust 代码时\n* 重构现有 Rust 代码时\n* 设计 crate 结构和模块布局时\n\n## 工作原理\n\n此技能在六个关键领域强制执行惯用的 Rust 约定：所有权和借用，用于在编译时防止数据竞争；`Result`\u002F`?` 错误传播，库使用 `thiserror` 而应用程序使用 `anyhow`；枚举和穷尽模式匹配，使非法状态无法表示；用于零成本抽象的 trait 和泛型；通过 `Arc\u003CMutex\u003CT>>`、通道和 async\u002Fawait 实现的安全并发；以及按领域组织的最小化 `pub` 接口。\n\n## 核心原则\n\n### 1. 所有权和借用\n\nRust 的所有权系统在编译时防止数据竞争和内存错误。\n\n```rust\n\u002F\u002F Good: Pass references when you don't need ownership\nfn process(data: &[u8]) -> usize {\n    data.len()\n}\n\n\u002F\u002F Good: Take ownership only when you need to store or consume\nfn store(data: Vec\u003Cu8>) -> Record {\n    Record { payload: data }\n}\n\n\u002F\u002F Bad: Cloning unnecessarily to avoid borrow checker\nfn process_bad(data: &Vec\u003Cu8>) -> usize {\n    let cloned = data.clone(); \u002F\u002F Wasteful — just borrow\n    cloned.len()\n}\n```\n\n### 使用 `Cow` 实现灵活的所有权\n\n```rust\nuse std::borrow::Cow;\n\nfn normalize(input: &str) -> Cow\u003C'_, str> {\n    if input.contains(' ') {\n        Cow::Owned(input.replace(' ', \"_\"))\n    } else {\n        Cow::Borrowed(input) \u002F\u002F Zero-cost when no mutation needed\n    }\n}\n```\n\n## 错误处理\n\n### 使用 `Result` 和 `?` —— 切勿在生产环境中使用 `unwrap()`\n\n```rust\n\u002F\u002F Good: Propagate errors with context\nuse anyhow::{Context, Result};\n\nfn load_config(path: &str) -> Result\u003CConfig> {\n    let content = std::fs::read_to_string(path)\n        .with_context(|| format!(\"failed to read config from {path}\"))?;\n    let config: Config = toml::from_str(&content)\n        .with_context(|| format!(\"failed to parse config from {path}\"))?;\n    Ok(config)\n}\n\n\u002F\u002F Bad: Panics on error\nfn load_config_bad(path: &str) -> Config {\n    let content = std::fs::read_to_string(path).unwrap(); \u002F\u002F Panics!\n    toml::from_str(&content).unwrap()\n}\n```\n\n### 库错误使用 `thiserror`，应用程序错误使用 `anyhow`\n\n```rust\n\u002F\u002F Library code: structured, typed errors\nuse thiserror::Error;\n\n#[derive(Debug, Error)]\npub enum StorageError {\n    #[error(\"record not found: {id}\")]\n    NotFound { id: String },\n    #[error(\"connection failed\")]\n    Connection(#[from] std::io::Error),\n    #[error(\"invalid data: {0}\")]\n    InvalidData(String),\n}\n\n\u002F\u002F Application code: flexible error handling\nuse anyhow::{bail, Result};\n\nfn run() -> Result\u003C()> {\n    let config = load_config(\"app.toml\")?;\n    if config.workers == 0 {\n        bail!(\"worker count must be > 0\");\n    }\n    Ok(())\n}\n```\n\n### 优先使用 `Option` 组合子而非嵌套匹配\n\n```rust\n\u002F\u002F Good: Combinator chain\nfn find_user_email(users: &[User], id: u64) -> Option\u003CString> {\n    users.iter()\n        .find(|u| u.id == id)\n        .map(|u| u.email.clone())\n}\n\n\u002F\u002F Bad: Deeply nested matching\nfn find_user_email_bad(users: &[User], id: u64) -> Option\u003CString> {\n    match users.iter().find(|u| u.id == id) {\n        Some(user) => match &user.email {\n            email => Some(email.clone()),\n        },\n        None => None,\n    }\n}\n```\n\n## 枚举和模式匹配\n\n### 将状态建模为枚举\n\n```rust\n\u002F\u002F Good: Impossible states are unrepresentable\nenum ConnectionState {\n    Disconnected,\n    Connecting { attempt: u32 },\n    Connected { session_id: String },\n    Failed { reason: String, retries: u32 },\n}\n\nfn handle(state: &ConnectionState) {\n    match state {\n        ConnectionState::Disconnected => connect(),\n        ConnectionState::Connecting { attempt } if *attempt > 3 => abort(),\n        ConnectionState::Connecting { .. } => wait(),\n        ConnectionState::Connected { session_id } => use_session(session_id),\n        ConnectionState::Failed { retries, .. } if *retries \u003C 5 => retry(),\n        ConnectionState::Failed { reason, .. } => log_failure(reason),\n    }\n}\n```\n\n### 穷尽匹配 —— 业务逻辑中不使用通配符\n\n```rust\n\u002F\u002F Good: Handle every variant explicitly\nmatch command {\n    Command::Start => start_service(),\n    Command::Stop => stop_service(),\n    Command::Restart => restart_service(),\n    \u002F\u002F Adding a new variant forces handling here\n}\n\n\u002F\u002F Bad: Wildcard hides new variants\nmatch command {\n    Command::Start => start_service(),\n    _ => {} \u002F\u002F Silently ignores Stop, Restart, and future variants\n}\n```\n\n## Trait 和泛型\n\n### 接受泛型，返回具体类型\n\n```rust\n\u002F\u002F Good: Generic input, concrete output\nfn read_all(reader: &mut impl Read) -> std::io::Result\u003CVec\u003Cu8>> {\n    let mut buf = Vec::new();\n    reader.read_to_end(&mut buf)?;\n    Ok(buf)\n}\n\n\u002F\u002F Good: Trait bounds for multiple constraints\nfn process\u003CT: Display + Send + 'static>(item: T) -> String {\n    format!(\"processed: {item}\")\n}\n```\n\n### 使用 Trait 对象进行动态分发\n\n```rust\n\u002F\u002F Use when you need heterogeneous collections or plugin systems\ntrait Handler: Send + Sync {\n    fn handle(&self, request: &Request) -> Response;\n}\n\nstruct Router {\n    handlers: Vec\u003CBox\u003Cdyn Handler>>,\n}\n\n\u002F\u002F Use generics when you need performance (monomorphization)\nfn fast_process\u003CH: Handler>(handler: &H, request: &Request) -> Response {\n    handler.handle(request)\n}\n```\n\n### 使用 Newtype 模式确保类型安全\n\n```rust\n\u002F\u002F Good: Distinct types prevent mixing up arguments\nstruct UserId(u64);\nstruct OrderId(u64);\n\nfn get_order(user: UserId, order: OrderId) -> Result\u003COrder> {\n    \u002F\u002F Can't accidentally swap user and order IDs\n    todo!()\n}\n\n\u002F\u002F Bad: Easy to swap arguments\nfn get_order_bad(user_id: u64, order_id: u64) -> Result\u003COrder> {\n    todo!()\n}\n```\n\n## 结构体和数据建模\n\n### 使用构建器模式进行复杂构造\n\n```rust\nstruct ServerConfig {\n    host: String,\n    port: u16,\n    max_connections: usize,\n}\n\nimpl ServerConfig {\n    fn builder(host: impl Into\u003CString>, port: u16) -> ServerConfigBuilder {\n        ServerConfigBuilder { host: host.into(), port, max_connections: 100 }\n    }\n}\n\nstruct ServerConfigBuilder { host: String, port: u16, max_connections: usize }\n\nimpl ServerConfigBuilder {\n    fn max_connections(mut self, n: usize) -> Self { self.max_connections = n; self }\n    fn build(self) -> ServerConfig {\n        ServerConfig { host: self.host, port: self.port, max_connections: self.max_connections }\n    }\n}\n\n\u002F\u002F Usage: ServerConfig::builder(\"localhost\", 8080).max_connections(200).build()\n```\n\n## 迭代器和闭包\n\n### 优先使用迭代器链而非手动循环\n\n```rust\n\u002F\u002F Good: Declarative, lazy, composable\nlet active_emails: Vec\u003CString> = users.iter()\n    .filter(|u| u.is_active)\n    .map(|u| u.email.clone())\n    .collect();\n\n\u002F\u002F Bad: Imperative accumulation\nlet mut active_emails = Vec::new();\nfor user in &users {\n    if user.is_active {\n        active_emails.push(user.email.clone());\n    }\n}\n```\n\n### 使用带有类型注解的 `collect()`\n\n```rust\n\u002F\u002F Collect into different types\nlet names: Vec\u003C_> = items.iter().map(|i| &i.name).collect();\nlet lookup: HashMap\u003C_, _> = items.iter().map(|i| (i.id, i)).collect();\nlet combined: String = parts.iter().copied().collect();\n\n\u002F\u002F Collect Results — short-circuits on first error\nlet parsed: Result\u003CVec\u003Ci32>, _> = strings.iter().map(|s| s.parse()).collect();\n```\n\n## 并发\n\n### 使用 `Arc\u003CMutex\u003CT>>` 处理共享可变状态\n\n```rust\nuse std::sync::{Arc, Mutex};\n\nlet counter = Arc::new(Mutex::new(0));\nlet handles: Vec\u003C_> = (0..10).map(|_| {\n    let counter = Arc::clone(&counter);\n    std::thread::spawn(move || {\n        let mut num = counter.lock().expect(\"mutex poisoned\");\n        *num += 1;\n    })\n}).collect();\n\nfor handle in handles {\n    handle.join().expect(\"worker thread panicked\");\n}\n```\n\n### 使用通道进行消息传递\n\n```rust\nuse std::sync::mpsc;\n\nlet (tx, rx) = mpsc::sync_channel(16); \u002F\u002F Bounded channel with backpressure\n\nfor i in 0..5 {\n    let tx = tx.clone();\n    std::thread::spawn(move || {\n        tx.send(format!(\"message {i}\")).expect(\"receiver disconnected\");\n    });\n}\ndrop(tx); \u002F\u002F Close sender so rx iterator terminates\n\nfor msg in rx {\n    println!(\"{msg}\");\n}\n```\n\n### 使用 Tokio 进行异步编程\n\n```rust\nuse tokio::time::Duration;\n\nasync fn fetch_with_timeout(url: &str) -> Result\u003CString> {\n    let response = tokio::time::timeout(\n        Duration::from_secs(5),\n        reqwest::get(url),\n    )\n    .await\n    .context(\"request timed out\")?\n    .context(\"request failed\")?;\n\n    response.text().await.context(\"failed to read body\")\n}\n\n\u002F\u002F Spawn concurrent tasks\nasync fn fetch_all(urls: Vec\u003CString>) -> Vec\u003CResult\u003CString>> {\n    let handles: Vec\u003C_> = urls.into_iter()\n        .map(|url| tokio::spawn(async move {\n            fetch_with_timeout(&url).await\n        }))\n        .collect();\n\n    let mut results = Vec::with_capacity(handles.len());\n    for handle in handles {\n        results.push(handle.await.unwrap_or_else(|e| panic!(\"spawned task panicked: {e}\")));\n    }\n    results\n}\n```\n\n## 不安全代码\n\n### 何时可以使用 Unsafe\n\n```rust\n\u002F\u002F Acceptable: FFI boundary with documented invariants (Rust 2024+)\n\u002F\u002F\u002F # Safety\n\u002F\u002F\u002F `ptr` must be a valid, aligned pointer to an initialized `Widget`.\nunsafe fn widget_from_raw\u003C'a>(ptr: *const Widget) -> &'a Widget {\n    \u002F\u002F SAFETY: caller guarantees ptr is valid and aligned\n    unsafe { &*ptr }\n}\n\n\u002F\u002F Acceptable: Performance-critical path with proof of correctness\n\u002F\u002F SAFETY: index is always \u003C len due to the loop bound\nunsafe { slice.get_unchecked(index) }\n```\n\n### 何时不可以使用 Unsafe\n\n```rust\n\u002F\u002F Bad: Using unsafe to bypass borrow checker\n\u002F\u002F Bad: Using unsafe for convenience\n\u002F\u002F Bad: Using unsafe without a Safety comment\n\u002F\u002F Bad: Transmuting between unrelated types\n```\n\n## 模块系统和 Crate 结构\n\n### 按领域组织，而非按类型\n\n```text\nmy_app\u002F\n├── src\u002F\n│   ├── main.rs\n│   ├── lib.rs\n│   ├── auth\u002F          # 领域模块\n│   │   ├── mod.rs\n│   │   ├── token.rs\n│   │   └── middleware.rs\n│   ├── orders\u002F        # 领域模块\n│   │   ├── mod.rs\n│   │   ├── model.rs\n│   │   └── service.rs\n│   └── db\u002F            # 基础设施\n│       ├── mod.rs\n│       └── pool.rs\n├── tests\u002F             # 集成测试\n├── benches\u002F           # 基准测试\n└── Cargo.toml\n```\n\n### 可见性 —— 最小化暴露\n\n```rust\n\u002F\u002F Good: pub(crate) for internal sharing\npub(crate) fn validate_input(input: &str) -> bool {\n    !input.is_empty()\n}\n\n\u002F\u002F Good: Re-export public API from lib.rs\npub mod auth;\npub use auth::AuthMiddleware;\n\n\u002F\u002F Bad: Making everything pub\npub fn internal_helper() {} \u002F\u002F Should be pub(crate) or private\n```\n\n## 工具集成\n\n### 基本命令\n\n```bash\n# Build and check\ncargo build\ncargo check              # Fast type checking without codegen\ncargo clippy             # Lints and suggestions\ncargo fmt                # Format code\n\n# Testing\ncargo test\ncargo test -- --nocapture    # Show println output\ncargo test --lib             # Unit tests only\ncargo test --test integration # Integration tests only\n\n# Dependencies\ncargo audit              # Security audit\ncargo tree               # Dependency tree\ncargo update             # Update dependencies\n\n# Performance\ncargo bench              # Run benchmarks\n```\n\n## 快速参考：Rust 惯用法\n\n| 惯用法 | 描述 |\n|-------|-------------|\n| 借用，而非克隆 | 传递 `&T`，除非需要所有权，否则不要克隆 |\n| 使非法状态无法表示 | 使用枚举仅对有效状态进行建模 |\n| `?` 优于 `unwrap()` | 传播错误，切勿在库\u002F生产代码中恐慌 |\n| 解析，而非验证 | 在边界处将非结构化数据转换为类型化结构体 |\n| Newtype 用于类型安全 | 将基本类型包装在 newtype 中以防止参数错位 |\n| 优先使用迭代器而非循环 | 声明式链更清晰且通常更快 |\n| 对 Result 使用 `#[must_use]` | 确保调用者处理返回值 |\n| 使用 `Cow` 实现灵活的所有权 | 当借用足够时避免分配 |\n| 穷尽匹配 | 业务关键枚举不使用通配符 `_` |\n| 最小化 `pub` 接口 | 内部 API 使用 `pub(crate)` |\n\n## 应避免的反模式\n\n```rust\n\u002F\u002F Bad: .unwrap() in production code\nlet value = map.get(\"key\").unwrap();\n\n\u002F\u002F Bad: .clone() to satisfy borrow checker without understanding why\nlet data = expensive_data.clone();\nprocess(&original, &data);\n\n\u002F\u002F Bad: Using String when &str suffices\nfn greet(name: String) { \u002F* should be &str *\u002F }\n\n\u002F\u002F Bad: Box\u003Cdyn Error> in libraries (use thiserror instead)\nfn parse(input: &str) -> Result\u003CData, Box\u003Cdyn std::error::Error>> { todo!() }\n\n\u002F\u002F Bad: Ignoring must_use warnings\nlet _ = validate(input); \u002F\u002F Silently discarding a Result\n\n\u002F\u002F Bad: Blocking in async context\nasync fn bad_async() {\n    std::thread::sleep(Duration::from_secs(1)); \u002F\u002F Blocks the executor!\n    \u002F\u002F Use: tokio::time::sleep(Duration::from_secs(1)).await;\n}\n```\n\n**请记住**：如果它能编译，那它很可能是正确的 —— 但前提是你要避免 `unwrap()`，最小化 `unsafe`，并让类型系统为你工作。\n",{"name":5,"origin":24,"description":7},"ECC","main","87afe6ce96220accf50a345dea46784c8c9f210e","YYC3-AI-应用工具\u002FYYC3-AI-应用工具-Everything-claude-code\u002Fdocs\u002Fzh-CN\u002Fskills\u002Frust-patterns",0,"https:\u002F\u002Fgithub.com\u002FYYC-Cube\u002FYYC3-Knowledge-Base","https:\u002F\u002Fkb.yyc3.top\u002F","https:\u002F\u002Fgithub.com\u002FYYC-Cube","万象归元于云枢 | 深栈智启新纪元","2026-11-10 10:37:32",{"source":8,"skillName":5,"commands":35,"prompt":45,"zipAvailable":46},[36,39,42],{"tool":37,"command":38},"npx","npx skills add YYC-Cube\u002FYYC3-Knowledge-Base --skill rust-patterns",{"tool":40,"command":41},"bunx","bunx skills add YYC-Cube\u002FYYC3-Knowledge-Base --skill rust-patterns",{"tool":43,"command":44},"pnpm","pnpm dlx skills add YYC-Cube\u002FYYC3-Knowledge-Base --skill rust-patterns","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002FYYC-Cube\u002FYYC3-Knowledge-Base\u002Fblob\u002Fmain\u002FYYC3-AI-应用工具\u002FYYC3-AI-应用工具-Everything-claude-code\u002Fdocs\u002Fzh-CN\u002Fskills\u002Frust-patterns\u002FSKILL.md",true,[],[49,56,63,70,77,84],{"skillNo":50,"name":51,"nameZh":6,"description":52,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":53,"categories":54,"keywords":55,"publishedAt":19},"01M7CTDWHERCXPQCP0K03A86AS","vercel-sandbox","Run agent-browser + Chrome inside Vercel Sandbox microVMs for browser automation from any Vercel-deployed app. Use when the user needs browser automation in a Vercel app (Next.js, SvelteKit, Nuxt, Remix, Astro, etc.), wants to run headless Chrome without binary size limits, needs persistent browser sessions across commands, or wants ephemeral isolated browser environments. Triggers include \"Vercel Sandbox browser\", \"microVM Chrome\", \"agent-browser in sandbox\", \"browser automation on Vercel\", or any task requiring Chrome in a Vercel Sandbox.","https:\u002F\u002Fgithub.com\u002FYYC-Cube\u002FYYC3-Knowledge-Base\u002Fblob\u002Fmain\u002FYYC3-WebSpec-Web标准\u002FYYC3-WebSpec-Web标准-standards\u002Fbrowser-agent\u002Fskills\u002Fvercel-sandbox\u002FSKILL.md",[],[],{"skillNo":57,"name":58,"nameZh":6,"description":59,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":60,"categories":61,"keywords":62,"publishedAt":19},"01M7CTD8D2BNJY54S65M47HEJA","slack","Interact with Slack workspaces using browser automation. Use when the user needs to check unread channels, navigate Slack, send messages, extract data, find information, search conversations, or automate any Slack task. Triggers include \"check my Slack\", \"what channels have unreads\", \"send a message to\", \"search Slack for\", \"extract from Slack\", \"find who said\", or any task requiring programmatic Slack interaction.","https:\u002F\u002Fgithub.com\u002FYYC-Cube\u002FYYC3-Knowledge-Base\u002Fblob\u002Fmain\u002FYYC3-WebSpec-Web标准\u002FYYC3-WebSpec-Web标准-standards\u002Fbrowser-agent\u002Fskills\u002Fslack\u002FSKILL.md",[],[],{"skillNo":64,"name":65,"nameZh":6,"description":66,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":67,"categories":68,"keywords":69,"publishedAt":19},"01M7CTCSSB8ZP3Q58C3YZDZK1W","electron","Automate Electron desktop apps (VS Code, Slack, Discord, Figma, Notion, Spotify, etc.) using agent-browser via Chrome DevTools Protocol. Use when the user needs to interact with an Electron app, automate a desktop app, connect to a running app, control a native app, or test an Electron application. Triggers include \"automate Slack app\", \"control VS Code\", \"interact with Discord app\", \"test this Electron app\", \"connect to desktop app\", or any task requiring automation of a native Electron application.","https:\u002F\u002Fgithub.com\u002FYYC-Cube\u002FYYC3-Knowledge-Base\u002Fblob\u002Fmain\u002FYYC3-WebSpec-Web标准\u002FYYC3-WebSpec-Web标准-standards\u002Fbrowser-agent\u002Fskills\u002Felectron\u002FSKILL.md",[],[],{"skillNo":71,"name":72,"nameZh":6,"description":73,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":74,"categories":75,"keywords":76,"publishedAt":19},"01M7CTCBJY76688V4DCZGWFHGQ","dogfood","Systematically explore and test a web application to find bugs, UX issues, and other problems. Use when asked to \"dogfood\", \"QA\", \"exploratory test\", \"find issues\", \"bug hunt\", \"test this app\u002Fsite\u002Fplatform\", or review the quality of a web application. Produces a structured report with full reproduction evidence -- step-by-step screenshots, repro videos, and detailed repro steps for every issue -- so findings can be handed directly to the responsible teams.","https:\u002F\u002Fgithub.com\u002FYYC-Cube\u002FYYC3-Knowledge-Base\u002Fblob\u002Fmain\u002FYYC3-WebSpec-Web标准\u002FYYC3-WebSpec-Web标准-standards\u002Fbrowser-agent\u002Fskills\u002Fdogfood\u002FSKILL.md",[],[],{"skillNo":78,"name":79,"nameZh":6,"description":80,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":81,"categories":82,"keywords":83,"publishedAt":19},"01M7CTC4H0FFGVEAQR9PA4GA1A","agent-browser","Browser automation CLI for AI agents. Use when the user needs to interact with websites, including navigating pages, filling forms, clicking buttons, taking screenshots, extracting data, testing web apps, or automating any browser task. Triggers include requests to \"open a website\", \"fill out a form\", \"click a button\", \"take a screenshot\", \"scrape data from a page\", \"test this web app\", \"login to a site\", \"automate browser actions\", or any task requiring programmatic web interaction.","https:\u002F\u002Fgithub.com\u002FYYC-Cube\u002FYYC3-Knowledge-Base\u002Fblob\u002Fmain\u002FYYC3-WebSpec-Web标准\u002FYYC3-WebSpec-Web标准-standards\u002Fbrowser-agent\u002Fskills\u002Fagent-browser\u002FSKILL.md",[],[],{"skillNo":85,"name":86,"nameZh":6,"description":87,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":88,"categories":89,"keywords":90,"publishedAt":19},"01M7CTBKVFYBG78FDSABSDJTTQ","shadcn","Manages shadcn components and projects — adding, searching, fixing, debugging, styling, and composing UI, including chat interfaces. Provides project context, component docs, and usage examples. Applies when working with shadcn\u002Fui, component registries, presets, --preset codes, or any project with a components.json file. Also triggers for \"shadcn init\", \"create an app with --preset\", \"switch to --preset\", and for building a design system or applying a DESIGN.md or brand spec to shadcn\u002Fui.","https:\u002F\u002Fgithub.com\u002FYYC-Cube\u002FYYC3-Knowledge-Base\u002Fblob\u002Fmain\u002FYYC3-UI-界面组件\u002FYYC3-UI-界面组件-ui\u002Fskills\u002Fshadcn\u002FSKILL.md",[],[]]