10.3 Enums with Data
Rust's enums can hold data associated with each variant, making them more powerful than C's enums and similar to a combination of C's enums and unions.
10.3.1 Defining Enums with Data
enum Message { Quit, Move { x: i32, y: i32 }, // Struct variant Write(String), // Tuple variant ChangeColor(i32, i32, i32), // Tuple variant }
- Variants:
Quit
: No data.Move
: A struct variant with named fieldsx
andy
.Write
: A tuple variant holding aString
.ChangeColor
: A tuple variant holding threei32
values.
Note: Enums with data can contain any type, including other enums, structs, tuples, or even themselves, allowing for nested and complex data structures.
10.3.2 Creating Instances
enum Message { Quit, Move { x: i32, y: i32 }, Write(String), ChangeColor(i32, i32, i32), } fn main() { let msg1 = Message::Quit; let msg2 = Message::Move { x: 10, y: 20 }; let msg3 = Message::Write(String::from("Hello")); let msg4 = Message::ChangeColor(255, 255, 0); }
- No Data Variant:
Message::Quit
requires no additional data. - Struct Variant:
Message::Move { x: 10, y: 20 }
uses named fields. - Tuple Variants:
Message::Write(String::from("Hello"))
andMessage::ChangeColor(255, 255, 0)
use positional data.
10.3.3 Comparison with C Unions
In C, to achieve similar functionality, you might use a union combined with an enum to track the active type.
#include <stdio.h>
#include <string.h>
enum MessageType {
Quit,
Move,
Write,
ChangeColor,
};
struct MoveData {
int x;
int y;
};
struct WriteData {
char text[50];
};
struct ChangeColorData {
int r;
int g;
int b;
};
union MessageData {
struct MoveData move;
struct WriteData write;
struct ChangeColorData color;
};
struct Message {
enum MessageType type;
union MessageData data;
};
int main() {
struct Message msg;
msg.type = Write;
strcpy(msg.data.write.text, "Hello");
if (msg.type == Write) {
printf("Write message: %s\n", msg.data.write.text);
}
return 0;
}
- Manual Management: You need to manually track the active variant using
type
. - No Type Safety: There's potential for errors if the
type
anddata
are mismatched. - Complexity: Requires more boilerplate code.
10.3.4 Advantages of Rust's Enums with Data
- Type Safety: Rust ensures that only the valid data for the current variant is accessible.
- Pattern Matching: Easily destructure and access data in a safe manner.
- Single Type: The enum is a single type, regardless of the variant, simplifying function signatures and data structures.