CodeBlanks Logo Icon CodeBlanks

Variants with data

Define enum variants that carry data.

Variants with data

The real power of Rust enums is that each variant can carry different data:

enum Mesaj {
    Cik,                       // no data
    Tasi { x: i32, y: i32 },   // struct form
    Yaz(String),               // tuple form
    Renk(u8, u8, u8),
}

let m = Mesaj::Tasi { x: 3, y: -1 };

Had we written four separate structs instead, gathering them into one type and passing them to the same function would be hard. The enum unites them all in one type.

Unpacking the data

In match arms the variant's data is bound to variables:

fn anlat(m: &Mesaj) -> String {
    match m {
        Mesaj::Cik => String::from("çıkış"),
        Mesaj::Tasi { x, y } => format!("taşı {x},{y}"),
        Mesaj::Yaz(metin) => format!("yaz: {metin}"),
        Mesaj::Renk(r, g, b) => format!("renk {r}/{g}/{b}"),
    }
}

When matching on &Mesaj, the bound variables are references too; ownership doesn't move.

Practice Describe the messages

Write the Mesaj enum above and the function fn anlat(m: &Mesaj) -> String. Loop over a vector containing Cik, Tasi { x: 3, y: -1 }, Yaz("selam") and Renk(0, 128, 255), and print each on its own line.

Starter code

main.rs
fn main() {
    // buraya yaz
}

Sample solution

main.rs
enum Mesaj {
    Cik,
    Tasi { x: i32, y: i32 },
    Yaz(String),
    Renk(u8, u8, u8),
}

fn anlat(m: &Mesaj) -> String {
    match m {
        Mesaj::Cik => String::from("çıkış"),
        Mesaj::Tasi { x, y } => format!("taşı {x},{y}"),
        Mesaj::Yaz(metin) => format!("yaz: {metin}"),
        Mesaj::Renk(r, g, b) => format!("renk {r}/{g}/{b}"),
    }
}

fn main() {
    let mesajlar = vec![
        Mesaj::Cik,
        Mesaj::Tasi { x: 3, y: -1 },
        Mesaj::Yaz(String::from("selam")),
        Mesaj::Renk(0, 128, 255),
    ];
    for m in &mesajlar {
        println!("{}", anlat(m));
    }
}

Expected output

çıkış
taşı 3,-1
yaz: selam
renk 0/128/255

Questions and answers

Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.

1 How do you reach the text inside <code>Mesaj::Yaz(String::from("a"))</code>?

  • With m.0
  • With m.Yaz
  • With as String
  • By pattern matching with match or if let Correct answer

Explanation: Variant data is only safely unpacked by pattern matching; the compiler needs to know the variant really is Yaz.

2 Struct variant

Question
let m = Mesaj::Tasi ____;
Answer
let m = Mesaj::Tasi { x: 3, y: -1 };

Explanation: A struct-form variant is created with braces and field names.

3 Variant and form

Term Meaning
Cik No data
Tasi { x, y } Struct form
Yaz(String) Tuple form, one field
Renk(u8, u8, u8) Tuple form, three fields

All lessons in Beginner