BudiBadu Logo
Samplebadu
Rust

Learn Rust by Examples

Rust 1.75+

Rust is a multi-paradigm, general-purpose programming language that emphasizes performance, type safety, and concurrency. It enforces memory safety—meaning that all references point to valid memory—without requiring a garbage collector.

This page provides comprehensive code samples to help learners understand Rust programming from basic syntax to advanced concepts like ownership, borrowing, and lifetimes. Each example includes complete, runnable code with line numbers, detailed explanations, and line-by-line breakdowns.

Hello World

Your first Rust program - the traditional starting point for learning any programming language. This code sample demonstrates the basic structure of a Rust application, including the main function entry point and the println! macro for output.

Variables & Mutability

Learn how Rust handles variable assignments with its unique approach to immutability. This example covers declaring variables with 'let', making them mutable with 'mut', and the powerful concept of variable shadowing.

Data Types

A comprehensive overview of Rust's type system. Explore scalar types like integers, floats, booleans, and characters, as well as compound types like tuples and arrays, understanding how Rust enforces type safety at compile time.

Ownership Basics

Master the most unique feature of Rust: Ownership. This example illustrates the three rules of ownership, the difference between stack and heap allocation, and how 'move' semantics prevent memory safety bugs without a garbage collector.

Borrowing & References

Learn how to use data without taking ownership of it. This guide explains immutable and mutable references, the rules of borrowing, and how Rust ensures memory safety through compile-time checks on reference validity.

Slices

Understand slices, a key primitive for efficient data access. This example shows how to create references to contiguous sequences of elements in a collection, such as string slices (&str) and array slices, avoiding unnecessary data copying.

Structs

Structure your data effectively using Structs. Learn to define custom data types with named fields, tuple structs, and unit structs, and see how to attach methods and associated functions using 'impl' blocks.

Enums

Explore the power of Rust's algebraic data types. This example demonstrates how to define Enums that can hold different types of data and how to use the 'match' operator for exhaustive pattern matching.

Control Flow

Master the flow of execution in your Rust programs. This guide covers 'if' expressions, unconditional 'loop' cycles, 'while' loops, and the idiomatic 'for' loop for iterating over collections safely and efficiently.

Error Handling

Handle runtime errors robustly using Rust's Result type. Learn the difference between recoverable and unrecoverable errors, how to pattern match on Results, and how to use the '?' operator for concise error propagation.

Custom Errors

Take control of your application's error reporting by defining custom error types. This example shows how to implement the std::error::Error trait and use enums to represent domain-specific failure modes.

Option Handling

Say goodbye to null pointer exceptions. This example demonstrates how to use the Option type to represent the presence or absence of a value, and how to safely handle these cases using combinators like map, unwrap_or, and if let.

Constants

Learn the difference between 'const' and 'static' for defining global values. This example explains when to use inlined constants versus fixed-address static variables and the implications for memory and safety.

Generics

Write flexible and reusable code with Generics. This guide explains how to define functions and structs that work with any type, and how to use trait bounds to restrict generics to types with specific behavior.

Traits

Define shared behavior across different types using Traits. Similar to interfaces in other languages, this example shows how to define traits, implement them for types, and use them to write polymorphic code.

Lifetimes Basics

Grasp the concept of Lifetimes, Rust's mechanism for ensuring references are valid. This example explains how the borrow checker uses lifetimes to prevent dangling pointers and ensure memory safety.

Lifetime Annotations

Dive deeper into explicit lifetime annotations. Learn syntax for annotating structs and function signatures to help the compiler understand relationships between the lifetimes of different references.

Smart Pointers

Unlock advanced memory management capabilities with Smart Pointers. This overview introduces the concept of types that act like pointers but have additional metadata, covering the Deref and Drop traits.

Box<T>

Learn to use Box<T>, the simplest smart pointer for heap allocation. This example demonstrates how to store data on the heap, create recursive types, and manage ownership of large data structures.

Rc & Arc

Enable multiple ownership of data with Reference Counting. This guide compares Rc (for single-threaded scenarios) and Arc (for multi-threaded scenarios), showing how to share data safely.

Threads Basics

Enter the world of concurrent programming. Learn how to spawn OS-level threads using std::thread, pass data to them using move closures, and synchronize their execution using join handles.

Channels

Communicate safely between threads using Channels. This example demonstrates the 'message passing' concurrency model, showing how to send data from multiple producers to a single consumer without sharing memory.

Mutex & Condvar

Coordinate thread access to shared resources. Learn to use Mutex for mutual exclusion and Condvar for thread signaling, essential primitives for implementing safe shared-state concurrency.

Shared State

Combine Arc and Mutex to share mutable state across threads. This example demonstrates the standard pattern for safe shared-state concurrency, ensuring data consistency in a multi-threaded environment.

Atomic Types

Achieve high-performance concurrency with Atomic types. Learn how to use lock-free primitives like AtomicUsize and AtomicBool to share simple data across threads without the overhead of mutexes.

Rayon Parallelism

Unlock easy data parallelism with Rayon. This example shows how to convert sequential iterators into parallel ones with a single method call, utilizing all CPU cores for data processing tasks.

Async Basics

Get started with Asynchronous Rust. This guide introduces the async/await syntax, explains how futures work under the hood, and demonstrates how to write non-blocking code for I/O-bound operations.

Futures & Await

Demystify the machinery behind async/await. This advanced example explores the Future trait, the polling mechanism, and how executors drive futures to completion.

Tokio

Build production-ready async applications with Tokio. Learn to use the most popular async runtime in Rust to spawn tasks, perform non-blocking I/O, and manage timers efficiently.

Async Channels

Coordinate asynchronous tasks using Tokio's channels. This example shows how to implement message passing between async tasks, handling backpressure and concurrency gracefully.

Concurrent Downloads

Execute multiple async operations in parallel. This practical example demonstrates how to use join_all to perform concurrent downloads, significantly reducing total wait time compared to sequential execution.

Rate Limiting

Control the flow of your async tasks with Rate Limiting. Learn to use Semaphores to restrict the number of concurrent operations, preventing resource exhaustion in high-load scenarios.

Async Timers

Master time-based async operations. This guide covers how to use Tokio's intervals for periodic tasks and timeouts to cancel long-running operations, essential for building responsive systems.

Async Errors

Handle errors seamlessly in asynchronous code. This example demonstrates that error handling in async Rust is just as ergonomic as in sync Rust, utilizing the Result type and the '?' operator.

Shared State Async

Safely share mutable state in an async environment. Learn why you should use Tokio's async Mutex instead of the standard library's Mutex when holding locks across await points to avoid deadlocks.

Async Streams

Process asynchronous sequences of data. Learn how to use the Stream trait (the async equivalent of Iterator) to handle data that arrives over time, such as network packets or sensor readings.