Rust Mixed-Type Vectors
A mixed-type Vec is a Vec whose slots hold different shapes through one enum. Each slot holds the enum.
One type per slot refuses a mixed row
A Vec holds one type only, so this spreadsheet row is refused:
let row = vec![3, "blue"]; // error E0308: the items must all be one typeWrap the choices in one enum
Every variant of an enum is the same type — the enum itself. So a Vec of the enum may hold a different shape in each slot:
enum Cell { Int(i32), Float(f64), Text(String) }
let row = vec![Cell::Int(3), Cell::Text(String::from("blue")), Cell::Float(10.12)];
println!("cells = {}", row.len());Read each shape back with match
match looks inside one cell. The compiler checks that every variant has an arm — you cannot forget one:
let cell = Cell::Float(2.5);
match cell {
Cell::Int(n) => println!("int {n}"),
Cell::Text(s) => println!("text {s}"),
Cell::Float(f) => println!("float {f}"),
}Example
enum SpreadsheetCell { Int(i32), Float(f64), Text(String) }
fn main() {
let row = vec![SpreadsheetCell::Int(3), SpreadsheetCell::Text(String::from("blue")), SpreadsheetCell::Float(10.12)];
for cell in &row {
match cell {
SpreadsheetCell::Int(n) => println!("int {}", n),
SpreadsheetCell::Text(s) => println!("text {}", s),
SpreadsheetCell::Float(f) => println!("float {}", f),
}
}
}Key points
- Rust knows the size at compile time.
- Each slot is as big as the biggest variant.
- It also holds a small tag.
- The tag says which variant it holds
In this example, SpreadsheetCell is an enum with three variants, one for each kind of cell. The Vec holds three cells, and every item is a SpreadsheetCell, so the one-type rule is kept. The for loop borrows each cell. match looks inside it. An Int prints its number. A Text prints its word. A Float prints its decimal. The output follows the row order: int 3, text blue, float 10.12.
Note
Use this trick when you know the full list of shapes in advance.
If the set of shapes is open-ended, a later tool (trait objects) fits better.
Try it Yourself
Edit the code, then press Run.
Running is simulated · Rust Playground
Exercise
Why can a Vec<SpreadsheetCell> hold an Int, a Text and a Float?