🌱
Dev Compendium
  • Ethereum
    • Solidity
      • EVM
      • Architecture
      • Execution Context
      • Transactions
      • Gas
      • Calldata, Memory & Storage
      • Gas Optimisation
      • Function Declarations
      • receive() & fallback()
      • CALL vs. DELEGATE CALL
    • Yul
      • Introduction
      • Types
      • Basic Operations
      • Storage
      • Memory
        • Arrays
        • Structs
        • Tuples, revert, keccak256
        • Logs and Events
        • Gotchas
        • abi.encode
      • Calldata
        • External Calls
        • Dynamic Length Inputs
        • Transferring Value
        • Receiving Contract Calls
      • Contracts in Yul
      • Other Yul Functions
    • Foundry
    • Security
      • Common Vulnerabilities
      • Best Practices
      • Development Workflow
      • Contract Migration
    • Auditing Tools
      • Slither
      • Mythril
      • Fuzzing
    • Upgradable Contracts
      • Upgrade Patterns
      • ERC-1967 Implementation
      • Deployment
    • MEV
    • Tooling
      • Chainlink
      • IPFS
      • Radicle
    • Frontend
      • Contract Hooks
      • Wallet Connection
        • wagmi.sh
        • Rainbow Kit
      • thirdweb
    • Protocol Research
      • Uniswap v2
      • Uniswap v3
      • Curve
      • GMX
  • Starkware
    • Fundamentals
    • Account Abstraction
    • Universal Deployer
    • Cairo 1.0
    • starknet.js
    • Security Model
  • Zero Knowledge
    • Group Theory
    • ECDSA
  • Rust
    • Basic Operations
    • Set up
    • Primitives
    • Control Flow
    • Mutability & Shadowing
    • Adding Behavior
    • Lifetimes
    • Std Library
  • SUI
    • Architecture
    • Consensus Mechanism
    • Local Node Setup
    • Sui Client CLI
    • Move Contracts
      • Move
      • Move.toml
      • Move.lock
      • Accessing Time in Sui Move
      • Set up Development Framework
      • Debug & Publish
      • Package Upgrades
      • Sui Move Library
      • Difference from Core Move
    • Object Programming
      • Object Basics
      • Using Objects
      • Immutable Objects
      • Object Wrapping
      • Dynamic Fields
      • Collections
      • Unit Testing
      • Deployment with CLI
  • NEAR
    • Architecture
    • Contract Standards
      • Fungible Token (NEP-141)
      • Non-Fungible Token (NEP-171)
      • Storage Management (NEP-145)
      • Events (NEP-297)
      • Meta-Transactions
    • Rust Contracts
      • Development Workflow
      • Smart Contract Layout
      • Storage Management
      • Events & Meta-transactions
      • Method Types
      • Upgrading Contracts
      • Unit Testing
    • NEAR Libraries
    • Environment Variables
    • Serialisation
    • Security Concepts
    • Collections
    • JS SDK
Powered by GitBook
On this page
  1. Rust

Control Flow

Rust has most of the control flow expressions you may expect, and a few you may not.

if

Compared to other curly-brace languages (like C++, Java, and JavaScript), Rust’s if statements have two notable differences:

  • Lack of the requirement for the condition expression to be enclosed in parentheses.

    • Example

  • if structures in Rust can be expressions as well as just normal statements. That is, they can resolve to a value like a ternary expression in JavaScript.

    • Example

while & loop

Rust has three looping structures. loop is the simplest: it just loops forever until it hits a break. while, like its namesake in other languages, loops while a condition holds (or until it hits a break). Similarly in style to the if statement, the while condition does not need to be enclosed in parentheses.

let mut x = 0; loop { if x >= 10 { break; } x += 1; }
let mut x = 0; while x < 10 { x += 1; }

The third looping structure is the for loop. It operates on any iterable type.

Arrays:

for i in [2, 4, 6, 8] { println!("{i}"); }

Output:

2 4 6 8

Ranges:

for i in 0..5 { println!("{i}"); }

Output:

0 1 2 3 4

There are other iterable structures, like [Vec](<https://doc.rust-lang.org/std/vec/struct.Vec.html>) and [HashSet](<https://doc.rust-lang.org/std/collections/struct.HashSet.html>), which you can explore if you wish.

match

Instead of the switch statement found in many other common languages, Rust opted for the more “functional” match construct.

`let operator = "*";

match operator { "+" => println!("add"), "-" => println!("subtract"), "*" => println!("multiply"), "/" => println!("divide"), _ => println!("unknown"), // _ is the catch-all pattern }`

`enum MediaType { Movie, Series { episodes: u32 }, }

let media_type: MediaType = /* ... */;

match media_type { MediaType::Movie => println!("It's a movie!"), // single line terminated with comma MediaType::Series { episodes } => { // multi-line enclosed in curly braces println!("It's a TV show!"); println!("It has {episodes} episodes!"); } }`

match expressions, since they are expressions, can also resolve to a value:

let unit_count = match media_type { MediaType::Series { episodes } => episodes, _ => 1, };

if let

This is equivalent to the previous listing:

let unit_count = if let MediaType::Series { episodes } = media_type { episodes } else { 1 };

PreviousPrimitivesNextMutability & Shadowing

Last updated 1 year ago

While matching against input cases using , you can also extract pieces from the input data using .

can perform destructuring as well. It’s like a conditional let.

Rust’s pattern matching syntax
destructuring
A special version of the if expression