Structs

How to create custom types with structs.

Beginner⏱️ 30 min📚 Prerequisites: 1

Structs

A struct allows us to create custom types that package multiple values together.

Basic Struct Definition

RUST
struct User {
    username: String,
    email: String,
    sign_in_count: u64,
    active: bool,
}

Creating Struct Instances

RUST
let user1 = User {
    email: String::from("someone@example.com"),
    username: String::from("someusername123"),
    active: true,
    sign_in_count: 1,
};

Accessing Fields

RUST
println!("{}", user1.email);
user1.sign_in_count += 1;

Mutable Struct

RUST
let mut user1 = User { /* ... */ };
user1.email = String::from("anotheremail@example.com");

Field Init Shorthand

RUST
fn build_user(email: String, username: String) -> User {
    User {
        email,      // instead of email: email
        username,   // instead of username: username
        active: true,
        sign_in_count: 1,
    }
}

Tuple Structs

RUST
struct Color(i32, i32, i32);
let black = Color(0, 0, 0);

Unit-like Structs

RUST
struct AlwaysEqual;
let subject = AlwaysEqual;

Code Examples

Basic Struct

Struct definition and usage

RUST
struct User {
    username: String,
    email: String,
    sign_in_count: u64,
    active: bool,
}
fn main() {
    let user1 = User {
        email: String::from("someone@example.com"),
        username: String::from("someusername123"),
        active: true,
        sign_in_count: 1,
    };
    println!("User: {}", user1.username);
    println!("Email: {}", user1.email);
}

Explanation:

A struct allows us to package related data together. Fields are accessed with dot notation.

Mutable Struct

Modifying a struct

RUST
struct User {
    username: String,
    email: String,
    sign_in_count: u64,
    active: bool,
}
fn main() {
    let mut user1 = User {
        email: String::from("someone@example.com"),
        username: String::from("someusername123"),
        active: true,
        sign_in_count: 1,
    };
    user1.sign_in_count += 1;
    println!("Sign-in count: {}", user1.sign_in_count);
}

Explanation:

To modify a struct, the variable must be `mut`. Then any field can be modified.

Tuple Struct

Using tuple structs

RUST
struct Color(i32, i32, i32);
struct Point(i32, i32, i32);
fn main() {
    let black = Color(0, 0, 0);
    let origin = Point(0, 0, 0);
    println!("Color RGB: ({}, {}, {})", black.0, black.1, black.2);
}

Explanation:

Tuple structs are useful when we want a distinct type but don't need field names. Elements are accessed by index.

Blockchain: Transaction Struct

Using structs for blockchain transactions

RUST
struct Transaction {
    from: String,
    to: String,
    amount: u64,
    fee: u64,
    nonce: u64,
}
fn main() {
    let tx = Transaction {
        from: String::from("0xAlice"),
        to: String::from("0xBob"),
        amount: 100,
        fee: 10,
        nonce: 1,
    };
    println!("Transaction:");
    println!("  From: {}", tx.from);
    println!("  To: {}", tx.to);
    println!("  Amount: {} tokens", tx.amount);
    println!("  Fee: {} tokens", tx.fee);
    println!("  Total: {} tokens", tx.amount + tx.fee);
}

Explanation:

Structs are perfect for representing blockchain transactions. They group related data (sender, receiver, amount, etc.) into a single type.

Blockchain: Account Struct

Representing blockchain accounts with structs

RUST
struct Account {
    address: String,
    balance: u64,
    nonce: u64,
    is_contract: bool,
}
impl Account {
    fn new(address: String) -> Self {
        Account {
            address,
            balance: 0,
            nonce: 0,
            is_contract: false,
        }
    }
    fn display(&self) {
        let account_type = if self.is_contract { "Contract" } else { "Wallet" };
        println!("{} Account: {}", account_type, self.address);
        println!("  Balance: {} tokens", self.balance);
        println!("  Nonce: {}", self.nonce);
    }
}
fn main() {
    let mut account = Account::new(String::from("0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb"));
    account.balance = 1000;
    account.display();
}

Explanation:

Account structs store blockchain account information. Methods can be added to structs using impl blocks for functionality like displaying account info.

Exercises

Creating a Struct

Create a Rectangle struct with width and height fields!

Easy

Starter Code:

RUST
fn main() {
}

Blockchain: Create Transaction

Create a Transaction struct for blockchain!

Easy

Starter Code:

RUST
fn main() {
}