Ownership: Comparison with Other Languages

2026-08-30 浏览 (1)

Ownership: Comparison with Other Languages

Rust vs C++

Memory Management

AspectRustC++
DefaultMove semanticsCopy semantics (pre-C++11)
Movelet b = a; (a invalidated)auto b = std::move(a); (a valid but unspecified)
Copylet b = a.clone();auto b = a;
SafetyCompile-time enforcementRuntime responsibility

Rust Move vs C++ Move

// Rust: after move, 'a' is INVALID
let a = String::from("hello");
let b = a;  // a moved
// println!("{}", a);  // COMPILE ERROR

// Equivalent in C++:
// std::string a = "hello";
// std::string b = std::move(a);
// std::cout << a;  // UNDEFINED (compiles but buggy)

Smart Pointers

RustC++Purpose
Box<T>std::unique_ptr<T>Unique ownership
Rc<T>std::shared_ptr<T>Shared ownership
Arc<T>std::shared_ptr<T> + atomicThread-safe shared
RefCell<T>(manual runtime checks)Interior mutability

Rust vs Go

Memory Model

AspectRustGo
MemoryStack + heap, explicitGC manages all
OwnershipEnforced at compile-timeNone (GC handles)
NullOption<T>nil for pointers
ConcurrencySend/Sync traitsChannels (less strict)

Sharing Data

// Rust: explicit about sharing
use std::sync::Arc;
let data = Arc::new(vec![1, 2, 3]);
let data_clone = Arc::clone(&data);
std::thread::spawn(move || {
    println!("{:?}", data_clone);
});

// Go: implicit sharing
// data := []int{1, 2, 3}
// go func() {
//     fmt.Println(data)  // potential race condition
// }()

Why No GC in Rust

  1. Deterministic destruction: Resources freed exactly when scope ends
  2. Zero-cost: No GC pauses or overhead
  3. Embeddable: Works in OS kernels, embedded systems
  4. Predictable latency: Critical for real-time systems

Rust vs Java/C#

Reference Semantics

AspectRustJava/C#
ObjectsOwned by defaultReference by default
NullOption<T>null (nullable)
ImmutabilityDefaultMust use final/readonly
CopyExplicit .clone()Reference copy (shallow)

Comparison

// Rust: clear ownership
fn process(data: Vec<i32>) {  // takes ownership
    // data is ours, will be freed at end
}

let numbers = vec![1, 2, 3];
process(numbers);
// numbers is invalid here

// Java: ambiguous ownership
// void process(List<Integer> data) {
//     // Who owns data? Caller? Callee? Both?
//     // Can caller still use it?
// }

Rust vs Python

Memory Model

AspectRustPython
TypingStatic, compile-timeDynamic, runtime
MemoryOwnership-basedReference counting + GC
MutabilityDefault immutableDefault mutable
PerformanceNative, zero-costInterpreted, higher overhead

Common Pattern Translation

// Rust: borrowing iteration
let items = vec!["a", "b", "c"];
for item in &items {
    println!("{}", item);
}
// items still usable

// Python: iteration doesn't consume
// items = ["a", "b", "c"]
// for item in items:
//     print(item)
// items still usable (different reason - ref counting)

Unique Rust Concepts

Concepts Other Languages Lack

  1. Borrow Checker: No other mainstream language has compile-time borrow checking
  2. Lifetimes: Explicit annotation of reference validity
  3. Move by Default: Values move, not copy
  4. No Null: Option<T> instead of null pointers
  5. Affine Types: Values can be used at most once

Learning Curve Areas

ConceptComing FromKey Insight
OwnershipGC languagesThink about who "owns" data
BorrowingC/C++Like references but checked
LifetimesAnyExplicit scope of validity
MoveC++Move is default, not copy

Mental Model Shifts

From GC Languages (Java, Go, Python)

Before: "Memory just works, GC handles it"
After:  "I explicitly decide who owns data and when it's freed"

Key shifts:

  • Think about ownership at design time
  • Returning references requires lifetime thinking
  • No more null - use Option<T>

From C/C++

Before: "I manually manage memory and hope I get it right"
After:  "Compiler enforces correctness, I fight the borrow checker"

Key shifts:

  • Trust the compiler's errors
  • Move is the default (unlike C++ copy)
  • Smart pointers are idiomatic, not overhead

From Functional Languages (Haskell, ML)

Before: "Everything is immutable, copying is fine"
After:  "Mutability is explicit, ownership prevents aliasing"

Key shifts:

  • Mutability is safe because of ownership rules
  • No persistent data structures needed (usually)
  • Performance characteristics are explicit

Performance Trade-offs

LanguageMemory OverheadLatencyThroughput
RustMinimal (no GC)PredictableExcellent
C++MinimalPredictableExcellent
GoGC overheadGC pausesGood
JavaGC overheadGC pausesGood
PythonHigh (ref counting + GC)VariableLower

When Rust Ownership Wins

  1. Real-time systems: No GC pauses
  2. Embedded: No runtime overhead
  3. High-performance: Zero-cost abstractions
  4. Concurrent: Data races prevented at compile time

When GC Might Be Preferable

  1. Rapid prototyping: Less mental overhead
  2. Complex object graphs: Cycles are tricky in Rust
  3. GUI applications: Object lifetimes are dynamic
  4. Small programs: Overhead doesn't matter

你可能感兴趣的文章

Ownership & Lifetimes

  • 所属分类: AI
  • 本文标签: rust
  • 版权声明: 本文链接 https://seaxiang.com/blog/WCyfRKRs