Token导航 LogoToken导航TokenDH.com
研究检索需要联网clawhub未标认证来源可访问clear审计通过

rust-devRust DEV 搜索

Agent Skill

rust-dev 用于记录任务执行中的错误、用户纠正、经验和能力缺口,适合在 OpenClaw 中希望让 Agent 持续沉淀问题、修正和最佳实践时使用。可结合来源仓库、安装命令和原始 README 继续核验具体用法。安装前建议确认权限范围、维护状态,以及是否会触发联网、命令执行或文件读写。

总安装

1,273

周安装

52

GitHub Stars

公开资料未说明

下载量

408
OpenClaw

安装说明

本站只整理中文说明和来源信息,不托管安装包,也不代用户安装。

GitHub

来源数

2

许可证

MIT-0

最后核验

2026-05-01

来源状态

来源可访问

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:rust-dev(Rust DEV 搜索)
来源仓库:https://github.com/tenequm/rust-dev
安装命令:
openclaw skills install rust-dev
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。该命令会通过 OpenClaw 从第三方来源获取 Skill;本站只展示命令,不托管安装包,也不自动执行。

ClawHubOpenClaw
openclaw skills install rust-dev

简介

提供 Rust 应用程序开发的实用第一天指南,涵盖核心概念解析。

  • 帮助开发者建立正确的心智模型,包括所有权、特征设计和第一天决策。
  • 适合新项目启动阶段参考,减少常见陷阱和架构失误。rust-dev 属于研究检索类 Skill,可作为该场景下的辅助能力补充。
  • 内容基于 Rust 2024 特性编写,需确保环境版本兼容性。
  • 建议结合实际案例练习,避免仅停留在理论层面理解。

SKILL.md

name
rust-dev
description
Practical day-1 guide to building applications in Rust well. Covers the mental model (ownership, errors as values, traits-not-interfaces), day-1 decisions (String vs &str, Box vs Rc vs Arc, dyn vs impl Trait, anyhow vs thiserror), idioms to internalize early, anti-patterns to avoid, and a tight crate shortlist (tokio, serde, anyhow, clap, reqwest, tracing, axum, sqlx). Use when starting a new Rust project, learning Rust coming from Python/JS/Go/Java/C++, deciding on types and lifetimes, choosing crates, structuring modules, configuring Cargo.toml/clippy/rustfmt, or whenever the user mentions Rust, cargo, ownership, borrow checker, lifetimes, traits, async Rust, or "writing this in Rust".
metadata
version
0.1.1
upstream
rust@1.95.0

Rust Development - Day 1

A practical foundation for writing Rust apps well from the first commit. Not a textbook. Focuses on the differences from other languages, the day-1 decisions that shape everything else, and the small set of crates that cover most real apps.

When to Use

  • Starting a new Rust project (CLI, service, library)
  • Coming to Rust from Python, JavaScript, Go, Java/C#, or C++
  • Choosing between owned/borrowed types, smart pointers, trait objects vs generics
  • Picking error handling strategy (anyhow vs thiserror)
  • Deciding which crates to reach for
  • Configuring a minimal but opinionated Cargo.toml, clippy, and rustfmt

Day-1 Setup

# 1. Install the toolchain (rustup is the toolchain manager)
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

# 2. Confirm components (rustfmt and clippy ship with stable, rust-src enables IDE features)
rustup component add rustfmt clippy rust-src

# 3. Create a project
cargo new my-app          # binary (src/main.rs)
cargo new --lib my-lib    # library (src/lib.rs)

# 4. The dev loop (memorize these four)
cargo check     # fast type-check, no codegen
cargo run       # build and run (binary)
cargo test      # build and run tests (incl. doctests)
cargo clippy    # lint (run before pushing)
cargo fmt       # format

# 5. Manage dependencies without editing Cargo.toml by hand
cargo add tokio --features full
cargo remove tokio

rust-analyzer is mandatory. It is the language server every editor uses (VS Code, Zed, Neovim, Helix, RustRover uses its own engine but is comparable). In VS Code, install the rust-analyzer extension and set rust-analyzer.check.command to "clippy" so you get lint feedback on save.

Want a file watcher later? cargo install bacon, then run bacon in your project. Not needed on day 1.

The Rust Mental Model in 5 Ideas

Rust trades two things you take for granted in most languages (a garbage collector and exceptions) for compile-time guarantees about memory, data races, and error handling. The shape of the language follows from that trade.

1. Ownership: every value has exactly one owner

Think of values like physical objects. A book, a file, a network connection. At any moment, one variable owns it. You can:

  • Move it: let b = a; hands ownership to b. a is gone.
  • Borrow it immutably: &a lets others look at it. Many readers allowed.
  • Borrow it mutably: &mut a lets one person modify it. Exclusive access.
  • Clone it: a.clone() makes a deep copy. Both keep their own.

When the owner goes out of scope, the value is dropped (memory freed, file closed, lock released). No GC, no manual free. This is RAII, enforced by the compiler.

2. Aliasing XOR mutability

At any moment, a piece of data has either:

  • one mutable reference (&mut T), or
  • any number of immutable references (&T),

never both. This single rule is what eliminates data races and most use-after-free bugs. The borrow checker enforces it. When it complains, it is telling you your data ownership story is unclear, not that the language is being difficult.

3. Errors are values, not exceptions

There is no try/catch. Functions that can fail return Result<T, E>. Functions that can return nothing useful return Option<T>. The compiler forces you to handle both. The ? operator propagates errors up the call stack with one character:

fn read_config() -> Result<Config, anyhow::Error> {
    let bytes = std::fs::read("config.toml")?;   // ? = early-return on Err
    let config = toml::from_slice(&bytes)?;
    Ok(config)
}

There is no null. Option<T> is None or Some(value). The compiler will not let you forget the None case.

4. Traits are not Java interfaces

A trait defines behavior. Types impl traits. So far so familiar. The differences:

  • Static dispatch is the default. When you write fn f<T: Display>(x: T), the compiler generates a separate copy of f for each concrete T you call it with (monomorphization, like C++ templates). Zero runtime overhead.
  • Dynamic dispatch is opt-in via dyn Trait (typically Box<dyn Trait> or &dyn Trait). One vtable lookup per call.
  • No inheritance. Traits compose. If you find yourself reaching for Deref to "extend" a type, stop and use composition or an enum.
  • Orphan rule: you can impl YourTrait for SomeoneElsesType or impl SomeoneElsesTrait for YourType, but not both foreign. This keeps dependency resolution sane.

5. The borrow checker is a design oracle

The most common newcomer mistake is treating compiler errors as obstacles to silence. They are not. Almost every borrow-check error reveals a real issue with who owns what. When you get stuck, the question is rarely "how do I make this compile" and almost always "what is the actual ownership relationship I want here?" Read the error. The compiler is unusually informative.

The 3 Questions for Every Function Signature

Before writing a function, ask: does it need to own, read, or modify the input?

fn consume(s: String)        // owns:    function takes responsibility, caller loses it
fn read(s: &str)             // reads:   function looks at it, caller keeps it
fn modify(s: &mut String)    // mutates: function changes it in place

Defaults that work 90% of the time:

  • Function parameters: prefer &str over String, &[T] over Vec<T> (these are slices, accept both owned and borrowed callers).
  • Function returns: return owned types (String, Vec<T>). Returning references means lifetimes; avoid until you need them.
  • Struct fields: prefer owned types (String, Vec<T>). Storing &str in a struct is the single most common newcomer trap and it cascades lifetime annotations through every type that holds your struct.

Day-1 Decision Table

One-line answers to the choices that come up first.

DecisionDefaultWhen to pick the other
String vs &str (struct field)StringAlmost never &str until you have a real reason and understand lifetimes
String vs &str (function param)&strUse String only if you must own/store it inside
Vec<T> vs &[T] (param)&[T]Vec<T> only if you must own
Box<T> vs Rc<T> vs Arc<T>Box<T> (single owner, heap)Arc<T> for shared ownership across threads. Avoid Rc<T> as default; use Arc<T> so you do not refactor when you go async
RefCell<T> vs Mutex<T>Mutex<T> (or RwLock<T>)Same reason: works in async/threads, while RefCell does not
Option<T> vs Result<T, E>Option<T> for "no value", Result<T, E> for "failed for a reason"If the absence carries meaning the caller should handle, Result
dyn Trait vs impl Trait / <T: Trait>Generic (<T: Trait> or impl Trait) - static dispatchBox<dyn Trait> when you need a heterogeneous collection (Vec<Box<dyn Animal>>)
Errors in app codeanyhow::Result<T> everywhere-
Errors in library codethiserror-derived enumNever Box<dyn Error> in public library APIs - forces callers to downcast
&self vs &mut self vs self&self for getters, &mut self for setters, self for builders/consuming ops-
Module layoutInline modules until a file gets long, then splitOne module = one file is a Java/C# instinct, not a Rust one

Idioms to Internalize Early

These appear in nearly every Rust program. Learn them in week 1.

? for error propagation. Replaces nine lines of match with one character.

let body = reqwest::get(url).await?.text().await?;

Iterator chains over manual loops. Compile to the same machine code as hand-written loops (LLVM inlines closures). Idiomatic Rust is functional in style.

let active_emails: Vec<String> = users
    .iter()
    .filter(|u| u.active)
    .map(|u| u.email.clone())
    .collect();

match exhaustiveness. Add a new variant to an enum and every match that does not handle it becomes a compile error. Use this. It is one of the most powerful refactoring tools in any language.

if let and let else for the common single-arm match.

if let Some(name) = user.name { println!("hi {name}"); }

let Some(name) = user.name else { return Err(anyhow!("no name")); };
// `name` is in scope from here on, no nesting

From / Into for type conversions. Implement From, get Into for free. ? uses From to convert error types automatically.

Combinators on Option / Result. Reach for .map, .and_then, .unwrap_or, .unwrap_or_else, .ok_or before reaching for match.

Derive macros. #[derive(Debug, Clone, PartialEq)] gets you 80% of the boilerplate for free. Add #[derive(Serialize, Deserialize)] for JSON.

Coming From X, Here Is What Bites You

From Python or JavaScript:

  • let b = a; for a heap value (like String, Vec) moves it. a is no longer usable. Use &a to borrow or a.clone() to copy.
  • No null. Option<T> is forced on you.
  • No exceptions. Result<T, E> and ?. The compiler will not let you ignore errors.
  • No inheritance. Composition + traits + enums.
  • Variables are immutable by default. Add mut to mutate. Same for references: & vs &mut.
  • Integer types are explicit and indexing requires usize.

From Go:

  • Errors as values - same instinct, but use ? instead of if err != nil.
  • No nil. Option<T>.
  • No GC and no goroutines: ownership + borrowing, async/await with tokio. The async model is cooperative (await is an explicit yield point), not preemptive.
  • interface{} becomes traits. Default to generics for static dispatch; Box<dyn Trait> only when you need it.
  • Static linking is the default. Binaries are bigger but self-contained.
  • panic! should be reserved for unrecoverable bugs in app code; do not use it as Go-style "log and continue".

From Java or C#:

  • Traits are not interfaces with virtual dispatch by default. <T: Trait> is monomorphized. dyn Trait is the opt-in dynamic version.
  • No null references. Option<T>.
  • No exceptions. Result<T, E> and ?.
  • No class inheritance. Use enums for sum types, traits for shared behavior.
  • No GC: ownership and borrowing decide lifetimes. Arc<T> is the closest thing to a Java reference.
  • Generics are monomorphized, not type-erased.

From C++:

  • Like RAII, but the borrow checker enforces it at compile time.
  • No copy/move constructors. Clone is explicit and Copy is a marker trait for cheap bitwise copies.
  • No undefined behavior in safe code (in theory).
  • & is a compile-time-checked borrow, not a raw pointer. Raw pointers exist (*const T, *mut T) but require unsafe to dereference.
  • Smart pointers are Box<T> (unique_ptr), Rc<T> (shared_ptr, single thread), Arc<T> (shared_ptr, thread-safe).
  • Macros are hygienic. Procedural macros (derive, attribute, function-like) are how serde, tokio::main, etc. work.

The Crate Shortlist

These cover most real apps. Add them as needed; they are not all required.

CrateWhat it gives you
serde + serde_jsonSerialization. #[derive(Serialize, Deserialize)] and you are done
tokioAsync runtime. #[tokio::main], tokio::spawn, async I/O
anyhowApp error type. anyhow::Result<T>, bail!, context()
thiserrorLibrary error enums. #[derive(thiserror::Error)]
clapCLI argument parsing. #[derive(Parser)] and you have a CLI
reqwestHTTP client. Async by default, blocking feature available
tracing + tracing-subscriberStructured logging. The default for any async code (replaces log)
axumWeb framework. Built on tokio + hyper + tower. The 2026 default
sqlxDatabase access. Async, compile-time checked queries. PostgreSQL, MySQL, SQLite
chronoDates and times. (jiff is promising but not yet ecosystem-ready as of April 2026)

See references/crate-shortlist.md for one minimal example each.

Top Anti-Patterns to Avoid

These are the mistakes that show up in every newcomer's code review. Avoid them.

  1. Storing &str (or any reference) in a struct. Causes lifetime annotations to cascade through every caller. Use String until you have a profiler-backed reason not to.
  2. Rc<RefCell<T>> everywhere to simulate Python/JS object semantics. It works but is a code smell, and breaks the moment you need threading. Default to Arc<Mutex<T>> instead so you do not refactor.
  3. Box<dyn Error> in library public APIs. Forces callers to downcast. Define a typed error enum with thiserror. Box<dyn Error> is acceptable inside a binary, never in a published library.
  4. .unwrap() and .expect() outside prototypes and tests. Use ? and propagate. Reserve unwrap for truly impossible cases and add a comment explaining why it cannot fail.
  5. Brute-force .clone() until it compiles. Sometimes cloning is right, but if you are scattering .clone() to silence the borrow checker, the design is wrong. Step back and ask the 3 questions about who owns what.
  6. Trying to inherit via Deref. Deref is for smart-pointer-like wrappers, not for OOP-style "extends". Use composition.
  7. Reaching for unsafe. App developers should essentially never need it. unsafe does not turn off the borrow checker; it lets you do five specific things (deref raw pointers, call unsafe functions, access mutable statics, implement unsafe traits, access union fields) with the contract that you have manually verified the invariants.

What to Defer

You do not need these on day 1. Some you may never need.

  • Lifetimes in struct fields. Avoid by using owned types. The day you genuinely need them, you will know.
  • Pin, Future internals, manual poll impls. Just write async fn and .await.
  • unsafe and FFI. Almost never for app code.
  • Procedural macros. Library author territory.
  • Higher-ranked trait bounds (for<'a>), variance, PhantomData. Expert territory.
  • Cell, OnceCell, LazyLock, MaybeUninit. Reach for these when you have a specific reason.

Minimal Cargo.toml

Single-crate, edition 2024, opinionated lints. Drop into a fresh project.

[package]
name = "my-app"
version = "0.1.0"
edition = "2024"
rust-version = "1.85"

[dependencies]

[dev-dependencies]

[profile.release]
lto = "thin"
codegen-units = 1

# =============================================================================
# Lints. Loose-but-helpful: deny obvious bugs, warn on common smells, leave
# room to learn. Upgrade to clippy::pedantic later if you want the full ride.
# =============================================================================
[lints.rust]
unsafe_code     = "forbid"   # downgrade to "deny" if you do FFI
unreachable_pub = "warn"

[lints.clippy]
all = { level = "deny", priority = -1 }
# Idiomatic helpers
uninlined_format_args         = "warn"
semicolon_if_nothing_returned = "warn"
implicit_clone                = "warn"
# Smells in non-prototype code
unwrap_used  = "warn"
expect_used  = "warn"
dbg_macro   = "warn"
todo        = "warn"
print_stdout = "warn"   # use `tracing::info!` instead in real apps

rustfmt.toml

style_edition = "2024"
edition       = "2024"

That is enough. rustfmt's defaults are good. Some teams add use_small_heuristics = "Max" to keep more code on single lines. Fancy options like imports_granularity and group_imports are still nightly-only as of April 2026.

rust-toolchain.toml (optional but recommended)

Pins the toolchain per-project so everyone on the team uses the same Rust.

[toolchain]
channel    = "stable"
components = ["rustfmt", "clippy", "rust-src"]
profile    = "minimal"

.gitignore

/target
**/*.rs.bk
Cargo.lock      # for libraries only; commit Cargo.lock for binaries

Project Structure

my-app/
  src/
    main.rs        # binary entry point: fn main()
    lib.rs         # OR a library crate root
    config.rs      # module: declared as `mod config;` in main.rs/lib.rs
    api/           # nested module
      mod.rs       # OR `api.rs` next to api/ folder (2018+ style preferred)
      users.rs
  tests/           # integration tests (each file is its own crate)
    smoke.rs
  Cargo.toml
  Cargo.lock
  rust-toolchain.toml
  rustfmt.toml
  .gitignore

Inline modules with mod { ... } until a file gets long, then split. Do not pre-split.

Learning Path

  1. The Rust Book (https://doc.rust-lang.org/book/) - canonical, free, current. The interactive Brown University version (https://rust-book.cs.brown.edu/) adds quizzes and visualizations.
  2. Rustlings (https://github.com/rust-lang/rustlings) - exercises in parallel with The Book.
  3. 100 Exercises to Learn Rust (https://rust-exercises.com/) - alternative or supplement to Rustlings, slightly newer.
  4. Rust for Rustaceans (Jon Gjengset) - the post-beginner book. Read after you are comfortable.
  5. Zero to Production in Rust (Luca Palmieri) - if you are building a backend service. Note: the book uses actix-web while axum is the 2026 default; the patterns translate cleanly.

For looking up syntax: Rust by Example (https://doc.rust-lang.org/rust-by-example/).

For curated crate recommendations: blessed.rs (https://blessed.rs/crates).

Reference Docs

Detailed material lives in references/. Read each when you hit the topic.

  • ownership-and-types.md - ownership, borrowing, lifetimes, String/&str/Cow, slices, smart pointers, the self-referential struct trap
  • error-handling.md - Result, ?, anyhow vs thiserror patterns, custom error enums, when panic! is appropriate
  • traits-and-generics.md - traits as bounds, dyn vs impl Trait vs generics, common derives, From/Into/Display/Debug, blanket impls, the orphan rule
  • async-basics.md - tokio, #[tokio::main], .await, Send/Sync, common pitfalls (blocking in async, MutexGuard across .await)
  • crate-shortlist.md - minimal usage example for each of the 8 crates above

适合场景

01

OpenClaw 用户查找和安装 Skill 时

02

用户想查找某类 Agent Skill 时

03

需要根据任务场景推荐可安装能力包时

04

需要对比不同来源的安装命令和来源信息时

能力概览

能力 1

按任务关键词查找相关 Skills

能力 2

展示可复制的安装命令

能力 3

保留来源站点、仓库和原始说明,方便继续核验

能力 4

补充不同宿主或平台的使用分布数据

能力 5

展示第三方安全扫描或审计结果

安装后应在对应宿主中按原始 README 的触发条件使用;具体调用方式请以来源页面和 README 为准。

平台分布

OpenClaw

85.98%
按下载量换算351

安全审计

VirusTotal

通过

ClawScan

通过

Static analysis

通过

权限和风险

需要联网

该 Skill 可能需要联网访问来源站点、仓库或外部 API;具体网络访问范围需要结合源码和 README 复核。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。当前只有一个来源,正式发布前建议补源仓库或其他目录站核验。

来源信息

继续浏览同类 Skills