373 lines
11 KiB
HTML
373 lines
11 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'; style-src 'self'; font-src 'self' data:; img-src 'self' data:; connect-src 'self'; base-uri 'self'; form-action 'self' https://defcon.social https://bsky.app;">
|
|
<meta http-equiv="X-Content-Type-Options" content="nosniff">
|
|
<link rel="stylesheet" href="../assets/css/style.css">
|
|
<link rel="icon" type="image/x-icon" href="../favicon.ico">
|
|
<script>
|
|
// Apply theme immediately to prevent flash
|
|
(function() {
|
|
const theme = localStorage.getItem('theme') ||
|
|
(window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light');
|
|
document.documentElement.setAttribute('data-theme', theme);
|
|
})();
|
|
</script>
|
|
<title>Rust Quickstart Reference - Quick Reference - Launch Pad</title>
|
|
</head>
|
|
<body>
|
|
<button class="theme-toggle" id="themeToggle" aria-label="Toggle dark mode">
|
|
<svg class="theme-icon theme-icon-moon" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"></path></svg>
|
|
<svg class="theme-icon theme-icon-sun" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="display: none;"><circle cx="12" cy="12" r="5"></circle><line x1="12" y1="1" x2="12" y2="3"></line><line x1="12" y1="21" x2="12" y2="23"></line><line x1="4.22" y1="4.22" x2="5.64" y2="5.64"></line><line x1="18.36" y1="18.36" x2="19.78" y2="19.78"></line><line x1="1" y1="12" x2="3" y2="12"></line><line x1="21" y1="12" x2="23" y2="12"></line><line x1="4.22" y1="19.78" x2="5.64" y2="18.36"></line><line x1="18.36" y1="5.64" x2="19.78" y2="4.22"></line></svg>
|
|
</button>
|
|
<br/><br/>
|
|
<div class="name">
|
|
__ _______________________ _________._________________________
|
|
\_ _____/ \______ \ / _ \ / _____/ / _____/ | | \_ _____/
|
|
| __) | _/ / /_\ \ / \ ___ / \ ___ | | | __)_
|
|
| \ | | \ / | \ \ \_\ \ \ \_\ \ | |___ | \
|
|
\___ / |____|_ / \____|__ / \______ / \______ / |_______ \ /_______ /
|
|
\/ \/ \/ \/ \/ \/ \/
|
|
</div>
|
|
<div class="blog-page-header">
|
|
<div class="blog-header-content">
|
|
<a href="/quickref" class="back-link" title="Back to Quick Reference">
|
|
<svg xmlns="http://www.w3.org/2000/svg" width="42" height="42" viewBox="0 0 24 24" class="home-icon"><path fill="currentColor" d="M10 20v-6h4v6h5v-8h3L12 3 2 12h3v8z"/></svg>
|
|
</a>
|
|
<h1 class="blog-page-title">Rust Quickstart Reference</h1>
|
|
</div>
|
|
</div>
|
|
<div class="blog-post-container">
|
|
<div class="blog-posts-container" style="max-width: 900px; margin: 0 auto;">
|
|
<div class="blog-post">
|
|
<div class="blog-post-content">
|
|
<p><a href="index.html">← Back to quick reference</a></p>
|
|
<p><a href="../index.html">← Home</a></p>
|
|
<hr>
|
|
<p>Quick reference guide for Rust. Essential syntax, ownership, borrowing, and common patterns.</p>
|
|
<hr>
|
|
<h2>Hello World</h2>
|
|
<pre><code>fn main() {
|
|
println!("Hello, World!"); // Semicolons required; braces define scope
|
|
}</code></pre>
|
|
<hr>
|
|
<h2>Variables</h2>
|
|
<pre><code>let x: i32 = 42; // Immutable by default
|
|
let mut y: i32 = 10; // Mutable
|
|
let name: &str = "Alice";
|
|
let flag: bool = true;
|
|
let pi: f64 = 3.14; // Floating point
|
|
|
|
// Type inference
|
|
let z = 100; // Compiler infers i32
|
|
let text = "Hello"; // &str
|
|
</code></pre>
|
|
<hr>
|
|
<h2>Control Flow</h2>
|
|
<h3>If/Else</h3>
|
|
<pre><code>if x > 10 {
|
|
println!("x is big");
|
|
} else {
|
|
println!("x is small");
|
|
}
|
|
|
|
if x > 10 {
|
|
println!("big");
|
|
} else if x > 5 {
|
|
println!("medium");
|
|
} else {
|
|
println!("small");
|
|
}
|
|
|
|
// If as expression
|
|
let result = if x > 10 { "big" } else { "small" };
|
|
</code></pre>
|
|
<h3>For Loops</h3>
|
|
<pre><code>for i in 0..5 { // 0 to 4 (exclusive)
|
|
println!("{}", i);
|
|
}
|
|
|
|
for i in 0..=5 { // 0 to 5 (inclusive)
|
|
println!("{}", i);
|
|
}
|
|
|
|
let nums = vec![1, 2, 3];
|
|
for n in &nums { // Borrow reference
|
|
println!("{}", n);
|
|
}
|
|
|
|
for (i, n) in nums.iter().enumerate() {
|
|
println!("{}: {}", i, n);
|
|
}
|
|
</code></pre>
|
|
<h3>While Loops</h3>
|
|
<pre><code>while y > 0 {
|
|
y -= 1;
|
|
println!("{}", y);
|
|
}
|
|
|
|
// Loop with break
|
|
loop {
|
|
if y <= 0 {
|
|
break;
|
|
}
|
|
y -= 1;
|
|
}
|
|
</code></pre>
|
|
<hr>
|
|
<h2>Functions</h2>
|
|
<pre><code>fn add(a: i32, b: i32) -> i32 {
|
|
a + b // Expression returns value (no semicolon)
|
|
}
|
|
|
|
println!("{}", add(2, 3));
|
|
|
|
// Explicit return
|
|
fn subtract(a: i32, b: i32) -> i32 {
|
|
return a - b; // Semicolon required with return
|
|
}
|
|
|
|
// Unit type (no return value)
|
|
fn greet() {
|
|
println!("Hello!");
|
|
}
|
|
</code></pre>
|
|
<hr>
|
|
<h2>Vectors / HashMaps</h2>
|
|
<h3>Vectors</h3>
|
|
<pre><code>let nums = vec![1, 2, 3]; // Dynamic array
|
|
for n in &nums {
|
|
println!("{}", n);
|
|
}
|
|
|
|
let mut vec = Vec::new();
|
|
vec.push(1);
|
|
vec.push(2);
|
|
vec.pop(); // Remove and return last item
|
|
vec[0] // Access by index
|
|
vec.len() // Length
|
|
</code></pre>
|
|
<h3>HashMaps</h3>
|
|
<pre><code>use std::collections::HashMap;
|
|
|
|
let mut person = HashMap::new();
|
|
person.insert("name", "Alice");
|
|
person.insert("age", "30");
|
|
println!("{}", person["name"]);
|
|
|
|
// Safe access
|
|
match person.get("name") {
|
|
Some(value) => println!("{}", value),
|
|
None => println!("Not found"),
|
|
}
|
|
|
|
// Or use unwrap_or
|
|
let name = person.get("name").unwrap_or(&"Unknown");
|
|
</code></pre>
|
|
<h3>Arrays</h3>
|
|
<pre><code>let arr = [1, 2, 3]; // Fixed-size array
|
|
let arr: [i32; 3] = [1, 2, 3]; // Explicit type and size
|
|
</code></pre>
|
|
<h3>Tuples</h3>
|
|
<pre><code>let point = (3, 4);
|
|
let (x, y) = point; // Destructuring
|
|
let x = point.0; // Access by index
|
|
</code></pre>
|
|
<hr>
|
|
<h2>Strings</h2>
|
|
<pre><code>let s1 = "Hello"; // &str (string slice)
|
|
let s2 = String::from("Hello"); // String (owned)
|
|
let s3 = s2.clone(); // Clone owned string
|
|
|
|
// String operations
|
|
let mut s = String::from("Hello");
|
|
s.push_str(" World");
|
|
s.push('!');
|
|
let len = s.len();
|
|
let slice = &s[0..5]; // String slice
|
|
|
|
// Formatting
|
|
let name = "Alice";
|
|
let greeting = format!("Hello, {}!", name);
|
|
</code></pre>
|
|
<hr>
|
|
<h2>Ownership & Borrowing</h2>
|
|
<pre><code>// Ownership
|
|
let s1 = String::from("hello");
|
|
let s2 = s1; // s1 moved to s2, s1 no longer valid
|
|
// println!("{}", s1); // Error! s1 no longer owns the value
|
|
|
|
// Borrowing (references)
|
|
let s1 = String::from("hello");
|
|
let len = calculate_length(&s1); // Borrow, don't move
|
|
println!("{}", s1); // Still valid
|
|
|
|
fn calculate_length(s: &String) -> usize {
|
|
s.len()
|
|
}
|
|
|
|
// Mutable references
|
|
let mut s = String::from("hello");
|
|
change(&mut s);
|
|
|
|
fn change(some_string: &mut String) {
|
|
some_string.push_str(", world");
|
|
}
|
|
</code></pre>
|
|
<hr>
|
|
<h2>Structs</h2>
|
|
<pre><code>struct Person {
|
|
name: String,
|
|
age: u32,
|
|
}
|
|
|
|
let person = Person {
|
|
name: String::from("Alice"),
|
|
age: 30,
|
|
};
|
|
|
|
println!("{} is {}", person.name, person.age);
|
|
|
|
// Methods
|
|
impl Person {
|
|
fn new(name: String, age: u32) -> Person {
|
|
Person { name, age }
|
|
}
|
|
|
|
fn greet(&self) {
|
|
println!("Hello, I'm {}", self.name);
|
|
}
|
|
}
|
|
|
|
let person = Person::new(String::from("Alice"), 30);
|
|
person.greet();
|
|
</code></pre>
|
|
<hr>
|
|
<h2>Enums</h2>
|
|
<pre><code>enum Direction {
|
|
Up,
|
|
Down,
|
|
Left,
|
|
Right,
|
|
}
|
|
|
|
let dir = Direction::Up;
|
|
|
|
match dir {
|
|
Direction::Up => println!("Going up"),
|
|
Direction::Down => println!("Going down"),
|
|
Direction::Left => println!("Going left"),
|
|
Direction::Right => println!("Going right"),
|
|
}
|
|
|
|
// Enums with data
|
|
enum Option<T> {
|
|
Some(T),
|
|
None,
|
|
}
|
|
|
|
let some_number = Some(5);
|
|
let no_number: Option<i32> = None;
|
|
</code></pre>
|
|
<hr>
|
|
<h2>Error Handling</h2>
|
|
<pre><code>// Result type
|
|
fn divide(a: f64, b: f64) -> Result<f64, String> {
|
|
if b == 0.0 {
|
|
Err(String::from("Division by zero"))
|
|
} else {
|
|
Ok(a / b)
|
|
}
|
|
}
|
|
|
|
match divide(10.0, 2.0) {
|
|
Ok(result) => println!("Result: {}", result),
|
|
Err(e) => println!("Error: {}", e),
|
|
}
|
|
|
|
// Using unwrap (panics on error)
|
|
let result = divide(10.0, 2.0).unwrap();
|
|
|
|
// Using expect (custom panic message)
|
|
let result = divide(10.0, 2.0).expect("Division failed");
|
|
|
|
// Using ? operator (propagates error)
|
|
fn calculate() -> Result<f64, String> {
|
|
let x = divide(10.0, 2.0)?;
|
|
Ok(x * 2.0)
|
|
}
|
|
</code></pre>
|
|
<hr>
|
|
<h2>File Operations</h2>
|
|
<pre><code>use std::fs;
|
|
use std::io::{self, Write};
|
|
|
|
// Reading
|
|
let content = fs::read_to_string("file.txt")
|
|
.expect("Failed to read file");
|
|
|
|
// Writing
|
|
fs::write("file.txt", "Hello, World!")
|
|
.expect("Failed to write file");
|
|
|
|
// With error handling
|
|
match fs::read_to_string("file.txt") {
|
|
Ok(content) => println!("{}", content),
|
|
Err(e) => println!("Error: {}", e),
|
|
}
|
|
</code></pre>
|
|
<hr>
|
|
<h2>Tips</h2>
|
|
<ul>
|
|
<li>Rust variables are immutable by default; use <code>mut</code> to allow changes.</li>
|
|
</ul>
|
|
<ul>
|
|
<li><code>read_line</code> handles user input; parsing is required for numbers:
|
|
<pre><code>use std::io;
|
|
let mut input = String::new();
|
|
io::stdin().read_line(&mut input).expect("Failed to read");
|
|
let number: i32 = input.trim().parse().expect("Not a number");</code></pre>
|
|
</li>
|
|
</ul>
|
|
<ul>
|
|
<li>Ownership and borrowing rules prevent data races — Rust's core safety guarantee.</li>
|
|
</ul>
|
|
<ul>
|
|
<li><code>0..5</code> ranges are exclusive of the end value; use <code>0..=5</code> for inclusive.</li>
|
|
</ul>
|
|
<ul>
|
|
<li>Everything has a type; Rust's compiler is strict but helpful with error messages.</li>
|
|
</ul>
|
|
<ul>
|
|
<li>Use <code>&</code> for borrowing (references) and <code>&mut</code> for mutable borrowing.</li>
|
|
</ul>
|
|
<ul>
|
|
<li>Expressions (no semicolon) return values; statements (with semicolon) return unit <code>()</code>.</li>
|
|
</ul>
|
|
<ul>
|
|
<li>Use <code>match</code> for pattern matching — exhaustive and powerful.</li>
|
|
</ul>
|
|
<ul>
|
|
<li>Use <code>Option<T></code> for values that might not exist, <code>Result<T, E></code> for operations that might fail.</li>
|
|
</ul>
|
|
<ul>
|
|
<li>The <code>?</code> operator is syntactic sugar for propagating errors in functions that return <code>Result</code>.</li>
|
|
</ul>
|
|
<ul>
|
|
<li>Use <code>unwrap()</code> sparingly — prefer proper error handling with <code>match</code> or <code>?</code>.</li>
|
|
</ul>
|
|
<ul>
|
|
<li>Structs define data; <code>impl</code> blocks define methods and associated functions.</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<script async type="text/javascript" src="../blog/analytics.js"></script>
|
|
<script src="../theme.js"></script>
|
|
</body>
|
|
</html>
|
|
|