rust-ownership rust-borrowing rust-lifetimes rust-programming rust-concurrency rust-cheatsheet rust-basics rust-syntax rust-control-flow rust-functions
Rust Cheatsheet: A Comprehensive Guide to Rust Programming
This Rust cheatsheet provides a quick reference to essential Rust concepts, syntax, and functionalities. Whether you're a beginner or an experienced developer, this guide will help you quickly look up common Rust patterns and features.
1. Basic Syntax
Hello, World!
fn main() {
println!("Hello, world!");
}
Variables
- Immutable Variables (default):
let x = 5;
- Mutable Variables:
let mut x = 5;
x = 6;
- Constants:
const MAX_POINTS: u32 = 100_000;
Data Types
- Scalar Types:
i32
,u32
,f64
,bool
,char
- Compound Types: Tuples, Arrays
let tup: (i32, f64, u8) = (500, 6.4, 1);
let (x, y, z) = tup;
let a = [1, 2, 3, 4, 5];
2. Control Flow
If/Else
let number = 6;
if number % 4 == 0 {
println!("Number is divisible by 4");
} else if number % 3 == 0 {
println!("Number is divisible by 3");
} else {
println!("Number is not divisible by 4 or 3");
}
Loops
- Infinite Loop:
loop {
println!("Loop forever!");
}
- While Loop:
let mut number = 3;
while number != 0 {
println!("{}!", number);
number -= 1;
}
- For Loop:
let a = [10, 20, 30, 40, 50];
for element in a.iter() {
println!("The value is: {}", element);
}
3. Functions
Basic Function
fn main() {
println!("The result is: {}", add(5, 3));
}
fn add(x: i32, y: i32) -> i32 {
x + y
}
Return Values
Functions return the last expression without a semicolon:
fn five() -> i32 {
5
}
4. Ownership and Borrowing
Ownership
- Move Semantics:
let s1 = String::from("hello");
let s2 = s1; // s1 is now invalid
- Clone:
let s1 = String::from("hello");
let s2 = s1.clone(); // Deep copy
Borrowing
- Immutable Borrowing:
fn main() {
let s1 = String::from("hello");
let len = calculate_length(&s1);
println!("The length of '{}' is {}.", s1, len);
}
fn calculate_length(s: &String) -> usize {
s.len()
}
- Mutable Borrowing:
fn main() {
let mut s = String::from("hello");
change(&mut s);
}
fn change(s: &mut String) {
s.push_str(", world");
}
Slices
let s = String::from("hello world");
let hello = &s[0..5];
let world = &s[6..11];
5. Structs
Defining a Struct
struct User {
username: String,
email: String,
sign_in_count: u64,
active: bool,
}
Instantiating a Struct
let user1 = User {
username: String::from("someusername"),
email: String::from("someone@example.com"),
sign_in_count: 1,
active: true,
};
Struct Update Syntax
let user2 = User {
email: String::from("another@example.com"),
..user1
};
Tuple Structs
struct Color(i32, i32, i32);
let black = Color(0, 0, 0);
6. Enums
Defining an Enum
enum Message {
Quit,
Move { x: i32, y: i32 },
Write(String),
ChangeColor(i32, i32, i32),
}
Using Enums
let m = Message::Write(String::from("hello"));
match m {
Message::Quit => println!("Quit"),
Message::Move { x, y } => println!("Move to x: {}, y: {}", x, y),
Message::Write(text) => println!("Text: {}", text),
Message::ChangeColor(r, g, b) => println!("Change color to red: {}, green: {}, blue: {}", r, g, b),
}
7. Error Handling
Panic!
fn main() {
panic!("Crash and burn");
}
Result and `match`
use std::fs::File;
use std::io::ErrorKind;
fn main() {
let f = File::open("hello.txt");
let f = match f {
Ok(file) => file,
Err(ref error) if error.kind() == ErrorKind::NotFound => {
match File::create("hello.txt") {
Ok(fc) => fc,
Err(e) => panic!("Problem creating the file: {:?}", e),
}
},
Err(error) => {
panic!("Problem opening the file: {:?}", error)
},
};
}
Using `unwrap` and `expect`
let f = File::open("hello.txt").unwrap();
let f = File::open("hello.txt").expect("Failed to open hello.txt");
8. Traits
Defining a Trait
pub trait Summary {
fn summarize(&self) -> String;
}
Implementing a Trait
struct Article {
title: String,
content: String,
}
impl Summary for Article {
fn summarize(&self) -> String {
format!("{}, {}", self.title, self.content)
}
}
Default Trait Methods
pub trait Summary {
fn summarize(&self) -> String {
String::from("(Read more...)")
}
}
Trait Bounds
fn notify<T: Summary>(item: T) {
println!("Breaking news! {}", item.summarize());
}
9. Lifetimes
Basic Lifetime Annotation
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
if x.len() > y.len() {
x
} else {
y
}
}
Structs with Lifetimes
struct ImportantExcerpt<'a> {
part: &'a str,
}
10. Collections
Vectors
let mut v = Vec::new();
v.push(5);
v.push(6);
v.push(7);
let third = &v[2];
Hash Maps
use std::collections::HashMap;
let mut scores = HashMap::new();
scores.insert(String::from("Blue"), 10);
scores.insert(String::from("Yellow"), 50);
Iterating Over Collections
for i in &v {
println!("{}", i);
}
for (key, value) in &scores {
println!("{}: {}", key, value);
}
11. Concurrency
Threads
use std::thread;
use std::time::Duration;
fn main() {
thread::spawn(|| {
for i in 1..10 {
println!("hi number {} from the spawned thread!", i);
thread::sleep(Duration::from_millis(1));
}
});
for i in 1..5 {
println!("hi number {} from the main thread!", i);
thread::sleep(Duration::from_millis(1));
}
}
Channels
use std::sync::mpsc;
use std::thread;
fn main() {
let (tx, rx) = mpsc::channel();
thread::spawn(move || {
let val = String::from("hi");
tx.send(val).unwrap();
});
let received = rx.recv().unwrap();
println!("Got: {}", received);
}
12. Modules and Crates
Creating Modules
mod network {
pub fn connect() {
println!("connected");
}
}
Using Modules
fn main() {
network::connect();
}
External Crates
In Cargo.toml
:
[dependencies]
rand = "0.8.3"
In your code:
use rand::Rng;
fn main() {
let mut rng = rand::thread_rng();
let n: u8 =
rng.gen();
println!("Random number: {}", n);
}
13. Common Macros
`println!`
println!("Hello, {}!", "world");
`vec!`
let v = vec![1, 2, 3];
`format!`
let s = format!("{} {}", "Hello", "world");
14. Cargo
Creating a New Project
cargo new my_project
cd my_project
Building and Running
cargo build
cargo run
cargo check
Adding Dependencies
In Cargo.toml
:
[dependencies]
serde = "1.0"
serde_json = "1.0"
Running Tests
cargo test
15. Testing
Writing Tests
#[cfg(test)]
mod tests {
#[test]
fn it_works() {
assert_eq!(2 + 2, 4);
}
#[test]
fn another() {
panic!("This test will fail");
}
}
Running Tests
cargo test
16. Error Handling
Result and Option
fn divide(dividend: f64, divisor: f64) -> Result<f64, String> {
if divisor == 0.0 {
Err(String::from("Cannot divide by zero"))
} else {
Ok(dividend / divisor)
}
}
Unwrap and Expect
let file = File::open("hello.txt").unwrap();
let file = File::open("hello.txt").expect("File not found!");
Conclusion
This Rust cheatsheet covers the essentials you'll need while working with Rust, from basic syntax and control flow to advanced concepts like lifetimes, concurrency, and error handling. Keep this cheatsheet handy as you work with Rust to quickly recall the syntax and concepts you need.
Comments
Please log in to leave a comment.