forked from inancgumus/learnrust
-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.rs
92 lines (88 loc) · 2.53 KB
/
main.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
// An IP address can either be a version four or six, but not both.
//
// -> However, both versions are still fundamentally IP addresses.
// -> They should be treated as the same type.
//
// So, an IP address is a good candidate to be represented as an enum:
//
// enum IpAddrKind {
// V4,
// V6,
// }
//
// Usage:
//
// V4 are V6 "variants" are "namespaced" (::) within the IpAddrKind enum.
//
// let four = IpAddrKind::V4;
// let six = IpAddrKind::V6;
//
// You can put it in a struct:
//
// struct IpAddr {
// kind: IpAddrKind, // <-
// address: String,
// }
//
// Usage:
//
// let home = IpAddr {
// kind: IpAddrKind::V4,
// address: String::from("127.0.0.1"),
// };
//
// let loopback = IpAddr {
// kind: IpAddrKind::V6,
// address: String::from("::1"),
// };
//
// However, there is a better way.
// -> Instead of using a struct,
// -> You can associate values with each variant of an enum.
enum IpAddr {
// Enum variants can have associated values.
V4(u8, u8, u8, u8), // -> represents an IPv4 address.
V6(String), // -> represents an IPv6 address.
}
// Each variant of the Message can store something else.
enum Message {
Quit, // doesn't include anything
Move { x: i32, y: i32 }, // includes an anonymous struct
Write(String), // includes a String
ChangeColor(i32, i32, i32), // includes three i32 values
}
// Then you can easily use it with a fn like this:
//
// fn processMessage(m: Message) {}
//
// But if we were to use a struct for each variant instead,
// then we wouldn't be able to define a single type to hold
// these all, and use with a fn easily.
//
// struct QuitMessage;
// struct MoveMessage {
// x: i32,
// y: i32,
// }
// struct WriteMessage(String);
// struct ChangeColorMessage(i32, i32, i32);
//
// fn processQuitMessage(m: QuitMessage) {}
// fn processMoveMessage(m: MoveMessage) {}
// fn processWriteMessage(m: WriteMessage) {}
// fn processChangeColorMessage(m: ChangeColorMessage) {}
//
// You can also define methods on enums:
impl Message {
fn process(&self) {
// ...
}
}
fn main() {
// declaring enums with associated values.
let _home = IpAddr::V4(127, 0, 0, 1); // has an [4]u8 tuple
let _loopback = IpAddr::V6(String::from("::1")); // has a String
// declaring and calling a method.
let m = Message::Write(String::from("hi"));
m.process();
}