google-site-verification: google61fe8ba583a51912.html
Rust Syntax Detail Information

Introduction to Rust Syntax

Rust is a systems programming language that focuses on safety, speed, and concurrency. Its syntax draws inspiration from C and C++ but introduces modern concepts that make it both powerful and expressive. Understanding Rust's syntax is crucial for writing efficient and safe code.

Rust's syntax is designed to be:

  • Readable: Clear and intuitive code structure
  • Expressive: Complex ideas can be conveyed concisely
  • Safe: Syntax encourages memory-safe practices
  • Zero-cost: High-level abstractions without runtime overhead

1. Basic Syntax Elements

Comments

// This is a line comment /// This is a documentation comment for the following item fn example() {} /* This is a block comment that can span multiple lines */

Printing and Output

fn main() { // Basic printing println!("Hello, World!"); // With newline print!("Hello, "); // Without newline println!("World!"); // Formatted printing let name = "Alice"; let age = 30; println!("Name: {}, Age: {}", name, age); // Debug printing let numbers = vec![1, 2, 3]; println!("{:?}", numbers); // Debug output println!("{:#?}", numbers); // Pretty debug output }

2. Variables and Mutability

Variable Declaration

fn main() { // Immutable variable (default) let x = 5; // x = 6; // This would cause an error! // Mutable variable let mut y = 5; y = 6; // This is fine // Constants (always immutable) const MAX_POINTS: u32 = 100_000; // Type annotations let z: i32 = 5; let flo: f64 = 3.14; let is_true: bool = true; // Multiple variables let (a, b, c) = (1, 2, 3); }

Shadowing

fn main() { let x = 5; let x = x + 1; // Shadows previous x { let x = x * 2; // Inner scope shadow println!("Inner x: {}", x); // 12 } println!("Outer x: {}", x); // 6 }

3. Data Types

Primitive Types

fn main() { // Integers let a: i8 = -128; // Signed 8-bit let b: u8 = 255; // Unsigned 8-bit let c: i32 = -100; // Signed 32-bit (default) let d: usize = 100; // Architecture-dependent // Floating point let e: f32 = 3.14; // 32-bit float let f: f64 = 2.71828; // 64-bit float (default) // Boolean let g: bool = true; let h = false; // Character (4 bytes, Unicode) let i: char = 'z'; let j = '😻'; // Tuples let tup: (i32, f64, char) = (500, 6.4, 'q'); let (x, y, z) = tup; let first = tup.0; // Arrays (fixed size) let arr: [i32; 5] = [1, 2, 3, 4, 5]; let zeros = [0; 10]; // Array of 10 zeros let first = arr[0]; }

4. Functions

Basic Function Syntax

// Function definition fn add(x: i32, y: i32) -> i32 { x + y // Expression, no semicolon means return } // Function with multiple statements fn greet(name: &str) -> String { let greeting = format!("Hello, {}!", name); greeting // Return value } // Unit return type (nothing) fn do_something() { println!("Doing something"); } // Diverging function (never returns) fn forever() -> ! { loop { // infinite loop } } fn main() { let result = add(5, 3); println!("Result: {}", result); let message = greet("Alice"); println!("{}", message); }

5. Control Flow

Conditional Statements

fn main() { let number = 6; // if-else if number % 4 == 0 { println!("Divisible by 4"); } else if number % 3 == 0 { println!("Divisible by 3"); } else { println!("Not divisible by 4 or 3"); } // if as an expression let condition = true; let value = if condition { 5 } else { 6 }; println!("Value: {}", value); }

Loops

fn main() { // Infinite loop let mut counter = 0; loop { counter += 1; if counter == 5 { break; // Exit loop } if counter == 3 { continue; // Skip to next iteration } println!("Counter: {}", counter); } // Returning from loops let mut counter = 0; let result = loop { counter += 1; if counter == 10 { break counter * 2; // Return value } }; println!("Result: {}", result); // 20 // While loop let mut number = 3; while number != 0 { println!("{}!", number); number -= 1; } // For loop (range) for i in 1..5 { // 1 to 4 println!("i: {}", i); } for i in 1..=5 { // 1 to 5 inclusive println!("i: {}", i); } // For loop with iterator let arr = [10, 20, 30]; for element in arr.iter() { println!("Value: {}", element); } // Enumerate for (index, value) in arr.iter().enumerate() { println!("Index: {}, Value: {}", index, value); } }

6. Ownership and Borrowing

Ownership Rules

fn main() { // Ownership transfer let s1 = String::from("hello"); let s2 = s1; // s1 is moved to s2 // println!("{}", s1); // Error! s1 no longer valid // Clone (deep copy) let s1 = String::from("hello"); let s2 = s1.clone(); println!("s1 = {}, s2 = {}", s1, s2); // Both valid // Copy types (stack-only) let x = 5; let y = x; // x is copied, not moved println!("x = {}, y = {}", x, y); // Both valid }

Borrowing and References

fn main() { let s1 = String::from("hello"); let len = calculate_length(&s1); // Borrow s1 println!("Length of '{}' is {}", s1, len); // Mutable references let mut s = String::from("hello"); change(&mut s); println!("Changed: {}", s); // Multiple references rules let mut s = String::from("hello"); let r1 = &s; // No problem let r2 = &s; // No problem println!("{} and {}", r1, r2); // r1 and r2 are no longer used after this let r3 = &mut s; // No problem println!("{}", r3); } fn calculate_length(s: &String) -> usize { s.len() } // s goes out of scope, but nothing happens fn change(s: &mut String) { s.push_str(", world"); }

Slices

fn main() { let s = String::from("hello world"); // String slices let hello = &s[0..5]; let world = &s[6..11]; // Shorthand let slice1 = &s[..5]; // from start to 5 let slice2 = &s[6..]; // from 6 to end let whole = &s[..]; // entire string // Array slices let a = [1, 2, 3, 4, 5]; let slice = &a[1..3]; // [2, 3] // Function with slice parameter let word = first_word(&s); println!("First word: {}", word); } fn first_word(s: &str) -> &str { let bytes = s.as_bytes(); for (i, &item) in bytes.iter().enumerate() { if item == b' ' { return &s[0..i]; } } &s[..] }

7. Structs

Defining and Using Structs

// Struct definition struct User { username: String, email: String, sign_in_count: u64, active: bool, } // Tuple structs struct Color(i32, i32, i32); struct Point(i32, i32, i32); // Unit-like struct struct AlwaysEqual; fn main() { // Creating instances let user1 = User { email: String::from("[email protected]"), username: String::from("someusername123"), active: true, sign_in_count: 1, }; // Accessing fields println!("Email: {}", user1.email); // Mutable instance let mut user2 = User { email: String::from("[email protected]"), username: String::from("anotheruser"), active: true, sign_in_count: 1, }; user2.email = String::from("[email protected]"); // Struct update syntax let user3 = User { email: String::from("[email protected]"), username: String::from("thirduser"), ..user1 // Copy remaining fields from user1 }; // Tuple structs let black = Color(0, 0, 0); let origin = Point(0, 0, 0); // Unit-like struct let subject = AlwaysEqual; } // Function that returns a struct fn build_user(email: String, username: String) -> User { User { email, // Field init shorthand username, // Field init shorthand active: true, sign_in_count: 1, } }

Methods and Associated Functions

struct Rectangle { width: u32, height: u32, } impl Rectangle { // Method (takes self) fn area(&self) -> u32 { self.width * self.height } // Method with parameters fn can_hold(&self, other: &Rectangle) -> bool { self.width > other.width && self.height > other.height } // Associated function (doesn't take self) fn square(size: u32) -> Rectangle { Rectangle { width: size, height: size, } } } fn main() { let rect = Rectangle { width: 30, height: 50, }; println!("Area: {}", rect.area()); let square = Rectangle::square(20); // Called with :: println!("Square area: {}", square.area()); }

8. Enums and Pattern Matching

Enums

enum IpAddrKind { V4, V6, } // Enum with data enum IpAddr { V4(u8, u8, u8, u8), V6(String), } // Enum with different types enum Message { Quit, Move { x: i32, y: i32 }, Write(String), ChangeColor(i32, i32, i32), } impl Message { fn call(&self) { // method body } } fn main() { let four = IpAddrKind::V4; let six = IpAddrKind::V6; let home = IpAddr::V4(127, 0, 0, 1); let loopback = IpAddr::V6(String::from("::1")); let m = Message::Write(String::from("hello")); m.call(); }

Option Enum

fn main() { let some_number = Some(5); let some_string = Some("a string"); let absent_number: Option<i32> = None; // Option vs null-safe operations let x: i8 = 5; let y: Option<i8> = Some(5); // Need to handle Option before using value match y { Some(value) => println!("Sum: {}", x + value), None => println!("No value"), } }

Match Control Flow

enum Coin { Penny, Nickel, Dime, Quarter, } fn value_in_cents(coin: Coin) -> u8 { match coin { Coin::Penny => { println!("Lucky penny!"); 1 }, Coin::Nickel => 5, Coin::Dime => 10, Coin::Quarter => 25, } } // Match with patterns fn main() { let dice_roll = 9; match dice_roll { 3 => add_fancy_hat(), 7 => remove_fancy_hat(), other => move_player(other), // Catch-all } // If let syntax (simpler than match for one pattern) let some_value = Some(3); if let Some(3) = some_value { println!("three"); } } fn add_fancy_hat() {} fn remove_fancy_hat() {} fn move_player(num_spaces: u8) {}

9. Collections

Vectors

fn main() { // Creating vectors let mut v: Vec<i32> = Vec::new(); let v2 = vec![1, 2, 3]; // Adding elements v.push(5); v.push(6); v.push(7); // Reading elements let third: &i32 = &v[2]; println!("Third element: {}", third); match v.get(2) { Some(third) => println!("Third element: {}", third), None => println!("No third element"), } // Iterating for i in &v { println!("{}", i); } // Mutable iteration for i in &mut v { *i += 50; } // Storing different types with enum enum SpreadsheetCell { Int(i32), Float(f64), Text(String), } let row = vec![ SpreadsheetCell::Int(3), SpreadsheetCell::Text(String::from("blue")), SpreadsheetCell::Float(10.12), ]; }

Strings

fn main() { // Creating strings let mut s = String::new(); let s2 = "initial contents".to_string(); let s3 = String::from("initial contents"); // Updating strings let mut s = String::from("foo"); s.push_str("bar"); // push string slice s.push('!'); // push character // Concatenation let s1 = String::from("Hello, "); let s2 = String::from("world!"); let s3 = s1 + &s2; // s1 is moved here // Format macro let s1 = String::from("tic"); let s2 = String::from("tac"); let s3 = String::from("toe"); let s = format!("{}-{}-{}", s1, s2, s3); // String slicing (careful!) let hello = "Здравствуйте"; let s = &hello[0..4]; // "Зд" (each char is 2 bytes) // Iterating over strings for c in "नमस्ते".chars() { println!("{}", c); } for b in "नमस्ते".bytes() { println!("{}", b); } }

Hash Maps

use std::collections::HashMap; fn main() { let mut scores = HashMap::new(); scores.insert(String::from("Blue"), 10); scores.insert(String::from("Yellow"), 50); // Accessing values let team_name = String::from("Blue"); let score = scores.get(&team_name); match score { Some(s) => println!("Score: {}", s), None => println!("Team not found"), } // Iterating for (key, value) in &scores { println!("{}: {}", key, value); } // Updating scores.insert(String::from("Blue"), 25); // Overwrites // Entry API scores.entry(String::from("Blue")).or_insert(50); scores.entry(String::from("Red")).or_insert(50); // Updating based on old value let text = "hello world wonderful world"; let mut map = HashMap::new(); for word in text.split_whitespace() { let count = map.entry(word).or_insert(0); *count += 1; } println!("{:?}", map); // {"world": 2, "hello": 1, "wonderful": 1} }

10. Error Handling

Panic

fn main() { // Unrecoverable errors // panic!("crash and burn"); // Backtrace let v = vec![1, 2, 3]; // v[99]; // This would panic }

Result Enum

use std::fs::File; use std::io::ErrorKind; use std::io::Read; fn main() { // Basic Result handling let f = File::open("hello.txt"); let f = match f { Ok(file) => file, Err(error) => match error.kind() { ErrorKind::NotFound => match File::create("hello.txt") { Ok(fc) => fc, Err(e) => panic!("Problem creating file: {:?}", e), }, other_error => panic!("Problem opening file: {:?}", other_error), }, }; // Using unwrap and expect let f = File::open("hello.txt").unwrap(); // Panics on error let f = File::open("hello.txt").expect("Failed to open hello.txt"); } // Propagating errors fn read_username_from_file() -> Result<String, std::io::Error> { let f = File::open("hello.txt"); let mut f = match f { Ok(file) => file, Err(e) => return Err(e), }; let mut s = String::new(); match f.read_to_string(&mut s) { Ok(_) => Ok(s), Err(e) => Err(e), } } // Using ? operator fn read_username_from_file_short() -> Result<String, std::io::Error> { let mut f = File::open("hello.txt")?; let mut s = String::new(); f.read_to_string(&mut s)?; Ok(s) } // Even shorter fn read_username_from_file_shorter() -> Result<String, std::io::Error> { let mut s = String::new(); File::open("hello.txt")?.read_to_string(&mut s)?; Ok(s) }

11. Generics

Generic Functions

fn largest<T: PartialOrd>(list: &[T]) -> &T { let mut largest = &list[0]; for item in list { if item > largest { largest = item; } } largest } fn main() { let number_list = vec![34, 50, 25, 100, 65]; let result = largest(&number_list); println!("Largest number: {}", result); let char_list = vec!['y', 'm', 'a', 'q']; let result = largest(&char_list); println!("Largest char: {}", result); }

Generic Structs

struct Point<T> { x: T, y: T, } struct PointMixed<T, U> { x: T, y: U, } impl<T> Point<T> { fn x(&self) -> &T { &self.x } } impl Point<f32> { fn distance_from_origin(&self) -> f32 { (self.x.powi(2) + self.y.powi(2)).sqrt() } } fn main() { let integer = Point { x: 5, y: 10 }; let float = Point { x: 1.0, y: 4.0 }; let mixed = PointMixed { x: 5, y: 4.0 }; }

12. Traits

Defining and Implementing Traits

// Define trait trait Summary { fn summarize(&self) -> String; // Default implementation fn summarize_author(&self) -> String { String::from("(Read more...)") } } struct NewsArticle { headline: String, location: String, author: String, content: String, } impl Summary for NewsArticle { fn summarize(&self) -> String { format!("{}, by {} ({})", self.headline, self.author, self.location) } } struct Tweet { username: String, content: String, reply: bool, retweet: bool, } impl Summary for Tweet { fn summarize(&self) -> String { format!("{}: {}", self.username, self.content) } } // Traits as parameters fn notify(item: &impl Summary) { println!("Breaking news! {}", item.summarize()); } // Trait bound syntax fn notify_bound<T: Summary>(item: &T) { println!("Breaking news! {}", item.summarize()); } // Multiple trait bounds fn notify_multi<T: Summary + Display>(item: &T) {} // Where clause fn some_function<T, U>(t: &T, u: &U) -> i32 where T: Display + Clone, U: Clone + Debug, { 42 } // Returning types that implement traits fn returns_summarizable() -> impl Summary { Tweet { username: String::from("horse_ebooks"), content: String::from("of course, as you probably already know, people"), reply: false, retweet: false, } }

13. Lifetimes

Lifetime Annotations

// Basic lifetime annotation fn longest<'a>(x: &'a str, y: &'a str) -> &'a str { if x.len() > y.len() { x } else { y } } // Lifetime in structs struct ImportantExcerpt<'a> { part: &'a str, } // Multiple lifetimes fn complex<'a, 'b>(x: &'a str, y: &'b str) -> &'a str { x } // Static lifetime fn static_lifetime() -> &'static str { "This string lives forever" } fn main() { let string1 = String::from("abcd"); let string2 = "xyz"; let result = longest(string1.as_str(), string2); println!("The longest string is {}", result); let novel = String::from("Call me Ishmael. Some years ago..."); let first_sentence = novel.split('.').next().expect("Could not find a '.'"); let excerpt = ImportantExcerpt { part: first_sentence, }; }

Lifetime Elision Rules

// No explicit lifetimes needed (elision rules apply) fn first_word(s: &str) -> &str { let bytes = s.as_bytes(); for (i, &item) in bytes.iter().enumerate() { if item == b' ' { return &s[0..i]; } } &s[..] } // Methods with lifetimes impl<'a> ImportantExcerpt<'a> { fn level(&self) -> i32 { 3 } fn announce_and_return_part(&self, announcement: &str) -> &str { println!("Attention please: {}", announcement); self.part } }

14. Modules and Visibility

Module System

// lib.rs or main.rs mod front_of_house { pub mod hosting { pub fn add_to_waitlist() {} fn seat_at_table() {} } mod serving { fn take_order() {} fn serve_order() {} fn take_payment() {} } } // Bringing paths into scope use crate::front_of_house::hosting; pub fn eat_at_restaurant() { // Absolute path crate::front_of_house::hosting::add_to_waitlist(); // Relative path front_of_house::hosting::add_to_waitlist(); // Using 'use' hosting::add_to_waitlist(); } // Re-exporting pub use crate::front_of_house::hosting; // Nested paths use std::{cmp::Ordering, io}; use std::io::{self, Write}; // Glob operator use std::collections::*;

File Hierarchy Example

// src/lib.rs mod front_of_house; pub use crate::front_of_house::hosting; // src/front_of_house.rs pub mod hosting; // src/front_of_house/hosting.rs pub fn add_to_waitlist() {}

15. Advanced Features

Closures

fn main() { // Basic closure let add_one = |x| x + 1; println!("{}", add_one(5)); // Closure with type annotations let expensive_closure = |num: u32| -> u32 { println!("calculating slowly..."); num * 2 }; // Capturing environment let x = 4; let equal_to_x = |z| z == x; println!("{}", equal_to_x(5)); // Moving ownership into closure let y = vec![1, 2, 3]; let equal_to_y = move |z| z == y; // println!("{:?}", y); // y is moved, can't use here }

Iterators

fn main() { let v1 = vec![1, 2, 3]; // Creating iterator let v1_iter = v1.iter(); // Using iterator for val in v1_iter { println!("Got: {}", val); } // Iterator adapters let v1: Vec<i32> = vec![1, 2, 3]; let v2: Vec<_> = v1.iter().map(|x| x + 1).collect(); assert_eq!(v2, vec![2, 3, 4]); // Filter let v1: Vec<i32> = vec![1, 2, 3, 4, 5]; let evens: Vec<_> = v1.into_iter().filter(|x| x % 2 == 0).collect(); assert_eq!(evens, vec![2, 4]); // Custom iterator struct Counter { count: u32, } impl Counter { fn new() -> Counter { Counter { count: 0 } } } impl Iterator for Counter { type Item = u32; fn next(&mut self) -> Option<Self::Item> { self.count += 1; if self.count < 6 { Some(self.count) } else { None } } } let mut counter = Counter::new(); assert_eq!(counter.next(), Some(1)); assert_eq!(counter.next(), Some(2)); }

Smart Pointers

Box

fn main() { // Box for heap allocation let b = Box::new(5); println!("b = {}", b); // Recursive type with Box #[derive(Debug)] enum List { Cons(i32, Box<List>), Nil, } use List::{Cons, Nil}; let list = Cons(1, Box::new(Cons(2, Box::new(Cons(3, Box::new(Nil)))))); println!("{:?}", list); }

Rc (Reference Counting)

use std::rc::Rc; enum List { Cons(i32, Rc<List>), Nil, } fn main() { use List::{Cons, Nil}; let a = Rc::new(Cons(5, Rc::new(Cons(10, Rc::new(Nil))))); println!("count after creating a = {}", Rc::strong_count(&a)); let b = Cons(3, Rc::clone(&a)); println!("count after creating b = {}", Rc::strong_count(&a)); { let c = Cons(4, Rc::clone(&a)); println!("count after creating c = {}", Rc::strong_count(&a)); } println!("count after c goes out of scope = {}", Rc::strong_count(&a)); }

RefCell and Interior Mutability

use std::cell::RefCell; #[derive(Debug)] struct MockMessenger { sent_messages: RefCell<Vec<String>>, } impl MockMessenger { fn new() -> MockMessenger { MockMessenger { sent_messages: RefCell::new(vec![]), } } fn send(&self, message: &str) { self.sent_messages.borrow_mut().push(String::from(message)); // Can also borrow immutably let messages = self.sent_messages.borrow(); } } fn main() { let m = MockMessenger::new(); m.send("Hello"); m.send("World"); println!("{:?}", m.sent_messages.borrow()); }

Conclusion

Rust's syntax is designed to be expressive while maintaining safety and performance. Key takeaways:

  1. Ownership and Borrowing are unique to Rust and prevent memory bugs
  2. Pattern Matching with match and if let provides powerful control flow
  3. Traits enable polymorphic behavior without inheritance
  4. Generics provide code reuse with zero-cost abstractions
  5. Lifetimes ensure references are always valid
  6. The Module System organizes code hierarchically
  7. Error Handling with Result encourages explicit error management

This guide covers the essential syntax you'll need to write Rust code effectively. Practice these concepts and refer to the official Rust documentation for more detailed information.

Leave a Reply

Your email address will not be published. Required fields are marked *


Macro Nepal Helper