提示:本网站现在为维护调试状态

Rust Ownership & Borrowing: Lifetimes Explained

Choyeon
Choyeon
Sep 7, 2026 1 min read 399 Views
399 words 2,184 chars Updated Nov 8, 2026
Rust Ownership & Borrowing: Lifetimes Explained
Table of contents

Rust Ownership & Borrowing: Lifetimes Thoroughly Explained

Rust guarantees memory safety without a GC, powered by ownership and borrow checker. Validates legality at compile time with zero runtime cost but steepest learning curve.

Three Iron Ownership Rules

(1) Every value has exactly one owner. (2) When owner leaves scope value is dropped. (3) A value can have either one mutable reference OR any immutable references - never both at once. Most beginner lifetime errors violate #3.

use std::collections::HashMap;

#[derive(Debug, Clone)]
struct User { id: u32, username: String, profile: Option<Box<User>> }

struct UserCache<'a> {
    users: HashMap<u32, User>,
    last_accessed: Option<&'a User>,
}

impl<'a> UserCache<'a> {
    fn new() -> Self { Self { users: HashMap::new(), last_accessed: None } }
    fn insert(&mut self, user: User) { self.users.insert(user.id, user); }
    fn get(&'a mut self, id: u32) -> Option<&'a User> {
        if let Some(u) = self.users.get(&id) {
            self.last_accessed = Some(u);
            self.last_accessed
        } else { None }
    }
}

fn longest_str<'a>(x: &'a str, y: &'a str) -> &'a str { if x.len() >= y.len() { x } else { y } }

struct Parser<'s, 'b> where 's: 'b { source: &'s str, buffer: &'b mut [u8] }

impl<'s, 'b> Parser<'s, 'b> where 's: 'b {
    fn new(source: &'s str, buffer: &'b mut [u8]) -> Self { Self { source, buffer } }
}

fn main() {
    let s1 = String::from("hello");
    let s2 = s1.clone();
    println!("s1={s1}, s2={s2}");
    let a = String::from("short"); let b = String::from("longest string wins");
    println!("longest: {}", longest_str(&a, &b));
    let mut cache = UserCache::new();
    cache.insert(User { id: 1, username: "rosetta".into(), profile: None });
    let u = cache.get(1);
    println!("Got user: {:?}", u.map(|x| &x.username));
    let mut buf = vec![0u8; 1024];
    let p = Parser::new("input", buf.as_mut_slice());
    println!("Parser source len: {}", p.source.len());
}

Lifetime Annotations and Bounds

When functions/structs contain references, Rust needs explicit labels ('a, 'b) expressing validity relationships. Bound 's: 'b means lifetime 's outlives 'b - common in self-referential structs.

Common Error Root Cause Fix Pattern
use of moved value Ownership transferred already .clone() or borrow with &
cannot borrow X as mutable + immutable Borrow rule violated Narrow scopes / split blocks
missing lifetime specifier Compiler can't infer relation Add 'a tying inputs/outputs
lifetime may not live long enough Referenced value dropped earlier Extend scope / owning types

Best Practices

First versions use owning types everywhere (String/Vec/Box). After passing, convert parameters to references. Don't chase lifetime annotations prematurely - let compiler errors drive incremental fixes.

X微博Telegram

About the author

Poll

你最希望 Rosetta 优先加入哪项功能?

社区投票(演示数据,可后台删除)

Comments (4)

0 / 3000
运维老司机
运维老司机ops-notes.cnSep 14, 2026

写得太好了,终于搞懂了分布式事务的几种方案区别,收藏了!

云端漫步
云端漫步cloud-notes.cloudSep 13, 2026

补充一点:实际使用中如果遇到 MySQL 的 8 小时超时问题,可以在连接串里加 autoReconnect=true 参数,虽然官方不推荐但挺好用的。

考研加油鸭
考研加油鸭kaoyan-journey.xyzSep 12, 2026

作为一个刚入行的后端新人,这篇文章帮我理清了好多概念,谢谢博主持续输出高质量内容!

画画的小鱼
画画的小鱼fishgallery.artSep 12, 2026

好文!但是我觉得第三部分那个消息队列选型对比表有点偏向 Kafka 了,RocketMQ 在事务消息这块其实优势挺明显的。

Related posts

PostgreSQL Query Optimization Techniques

PostgreSQL Query Optimization Techniques

Master PostgreSQL optimization: EXPLAIN ANALYZE plans, choosing index types (B-tree/GIN/BRIN), updating statistics, tuning joins, and partitioned table design for maximum performance.

1 min read
Linux Performance Tuning: perf, bpftrace & BCC

Linux Performance Tuning: perf, bpftrace & BCC

Tune Linux across CPU/mem/IO/net: perf for CPU sampling, bpftrace one-liners for kernel tracepoints, BCC classics biolatency/offcputime to pinpoint production bottlenecks with real incident methodology.

1 min read
Getting Started with WebAssembly: Rust to WASM + JS

Getting Started with WebAssembly: Rust to WASM + JS

End-to-end Rust to WASM setup: wasm-pack toolchain, wasm-bindgen type bindings, JS sync/async invocation, TypedArray memory sharing for compute-heavy browser workloads.

1 min read
Zero Trust Security Architecture: Never Trust, Always Verify

Zero Trust Security Architecture: Never Trust, Always Verify

Zero Trust security model primer: built on "never trust, always verify" and dismantles traditional VPN-equals-trusted perimeter thinking. Six pillars explained — identity (MFA/SAML), device health checks, least-privilege RBAC, microsegmentation mTLS, continuous trust scoring, observable audit trail — with implementation roadmap.

1 min read
K8s Pod Lifecycle, Init Containers & Sidecars

K8s Pod Lifecycle, Init Containers & Sidecars

Full K8s Pod state machine Pending→Terminated, PostStart/PreStop hooks, Init Container dependency guarantees, Sidecar patterns (istio-proxy, log collectors), and zero-downtime graceful termination configs.

1 min read
Test Pyramid: Unit/Integration/E2E Ratios & Implementation

Test Pyramid: Unit/Integration/E2E Ratios & Implementation

Systematic test pyramid breakdown: bottom unit tests (many, fast, mock isolated), middle integration tests (real service/db/message interaction), top E2E tests (few, critical user flows). Recommended ratio 70/20/10, with coverage metrics and implementation playbook.

1 min read