1
00:00:02,240 --> 00:00:04,090
Structs, short for structures,
2
00:00:04,540 --> 00:00:07,190
are custom types that group related data together,
3
00:00:07,370 --> 00:00:13,669
such as all of the attributes of a hockey player. Recall the primitive data types from module 4 -
4
00:00:13,670 --> 00:00:17,089
we'll be building structs by putting primitive data types
5
00:00:17,090 --> 00:00:17,600
together.
6
00:00:19,440 --> 00:00:21,149
We'll be comparing and contrasting
7
00:00:21,150 --> 00:00:22,440
structs with enums,
8
00:00:22,570 --> 00:00:29,150
which we covered in module 7. In this module, we'll cover when structs are useful;
9
00:00:30,040 --> 00:00:30,209
we'll
10
00:00:30,210 --> 00:00:33,250
look at the syntax for defining and using a struct;
11
00:00:34,140 --> 00:00:36,600
we'll also discuss some other forms of structs,
12
00:00:37,040 --> 00:00:39,100
which are tuple structs and unit structs.
13
00:00:39,590 --> 00:00:44,839
We'll also briefly circle back to enums to show how you can define enum variants to have named
14
00:00:44,840 --> 00:00:45,779
fields like structs do.
15
00:00:48,040 --> 00:00:50,550
Let's get started with when structs are useful.
16
00:00:52,470 --> 00:00:54,159
Remember the HockeyPosition
17
00:00:54,160 --> 00:00:54,429
enum
18
00:00:54,430 --> 00:00:55,800
we created in the previous module?
19
00:00:56,690 --> 00:00:59,759
Let's say we now want to create a data type that models a
20
00:00:59,760 --> 00:01:00,750
hockey player -
21
00:01:01,340 --> 00:01:03,050
that would be a good fit for a struct.
22
00:01:05,180 --> 00:01:08,710
Every hockey player has a bunch of attributes that describe that player.
23
00:01:09,440 --> 00:01:10,540
They each have a name,
24
00:01:10,700 --> 00:01:11,370
a number,
25
00:01:11,670 --> 00:01:15,750
a position, and some stats like how many goals they've scored this year.
26
00:01:16,400 --> 00:01:19,650
This set of attributes is the same across all players,
27
00:01:20,240 --> 00:01:22,950
but each player has different values for these attributes.
28
00:01:23,440 --> 00:01:27,180
Putting values for these attributes together describes a particular hockey player.
29
00:01:29,240 --> 00:01:34,300
Describing a hockey player with a struct is a better fit than describing a hockey player with an enum
30
00:01:34,740 --> 00:01:37,850
because we're not choosing between different kinds of hockey players.
31
00:01:38,540 --> 00:01:42,610
An enum is for when you want to describe a choice between a set of values,
32
00:01:43,040 --> 00:01:44,550
such as choosing banana,
33
00:01:44,560 --> 00:01:46,950
apple, or orange from a set of fruits.
34
00:01:47,600 --> 00:01:52,250
A struct is for when you want to have the same attributes for all of the values of that type,
35
00:01:52,840 --> 00:01:57,450
such as multiple recipes that all have a list of ingredients and a list of directions.
36
00:01:59,690 --> 00:02:02,550
Let's look at how we define a hockey player struct in code.
37
00:02:04,480 --> 00:02:07,450
A struct definition starts with the struct keyword,
38
00:02:07,920 --> 00:02:10,529
then the name we want to use for the struct.
39
00:02:10,530 --> 00:02:15,150
Here, we've picked HockeyPlayer. Struct names, by convention, should be camel case.
40
00:02:16,340 --> 00:02:18,850
Next comes curly brackets, and, within them,
41
00:02:19,340 --> 00:02:23,150
a comma-separated list of the field names and types that make up the struct.
42
00:02:23,840 --> 00:02:27,660
Field names should be in snake case.
43
00:02:27,960 --> 00:02:36,050
For hockey player, we've got a name field that's a String, a number field that's a u8, a position field that has the type of our HockeyPosition enum,
44
00:02:36,840 --> 00:02:39,880
and a goals year-to-date field that is also u8.
45
00:02:42,090 --> 00:02:44,550
Now it's time to put this struct definition to use.
46
00:02:45,940 --> 00:02:48,450
Struct definitions list the set of attributes,
47
00:02:48,840 --> 00:02:55,859
and we can then fill in a struct with values to represent a particular instance. To instatiate
48
00:02:55,860 --> 00:02:59,450
a particular hockey player and store the data in a variable,
49
00:03:00,040 --> 00:03:02,250
we set the variable equal to the struct name,
50
00:03:02,740 --> 00:03:04,020
then open curly brackets,
51
00:03:04,660 --> 00:03:07,750
then list each field and the value we want each field to have.
52
00:03:08,240 --> 00:03:11,010
Remember to finish the assignment statement with a semicolon.
53
00:03:12,040 --> 00:03:15,250
It's required to initialize all the fields of the struct with the value.
54
00:03:16,040 --> 00:03:17,550
Once we have a struct instance,
55
00:03:17,940 --> 00:03:25,210
we can access the value in a particular field of the struct by using the variable name, then a dot, then the field we want to access.
56
00:03:27,540 --> 00:03:29,120
We can also change the values
57
00:03:29,130 --> 00:03:29,819
in an instance's
58
00:03:29,820 --> 00:03:32,950
fields as long as the instance is mutable.
59
00:03:34,180 --> 00:03:37,050
This code adds one to the goals year-to-date field,
60
00:03:37,840 --> 00:03:41,660
and the program now prints Bryan Rust has scored 8 goals this season.
61
00:03:43,880 --> 00:03:46,850
Having named fields is what most structs look like,
62
00:03:47,440 --> 00:03:49,950
but there are also tuple structs and unit structs.
63
00:03:50,840 --> 00:03:54,759
Let's look at those briefly. Tuple
64
00:03:54,760 --> 00:03:59,550
structs are structs that have a name for the whole type but don't name their fields.
65
00:04:00,540 --> 00:04:02,450
They behave similarly to tuples.
66
00:04:03,240 --> 00:04:06,030
You access their fields with a dot and an index,
67
00:04:06,040 --> 00:04:06,990
starting with zero.
68
00:04:08,140 --> 00:04:08,950
For example,
69
00:04:09,340 --> 00:04:11,440
here's a tuple struct named Triangle,
70
00:04:11,640 --> 00:04:15,150
defined to store the length of each of the three sides of a triangle.
71
00:04:17,490 --> 00:04:17,839
Tuple
72
00:04:17,840 --> 00:04:23,550
structs are useful to create types that are considered different from a plain tuple or other tuple structs
73
00:04:24,080 --> 00:04:26,550
as far as Rust's type checker is concerned.
74
00:04:27,500 --> 00:04:31,350
We can't pass a plain tuple to this function that only takes a triangle.
75
00:04:32,140 --> 00:04:32,890
If we try,
76
00:04:32,900 --> 00:04:33,920
we get a type error.
77
00:04:34,640 --> 00:04:41,050
Giving the tuple a name by using a tuple struct has made this a new type incompatible with other tuples.
78
00:04:43,440 --> 00:04:47,420
One common use of a tuple struct is called the newtype pattern,
79
00:04:47,940 --> 00:04:53,090
where an existing type is wrapped in a tuple struct with one element to add meaning.
80
00:04:54,140 --> 00:04:55,810
An example of this is wrapping
81
00:04:55,820 --> 00:04:57,950
a u8 in a struct named Meters,
82
00:04:58,510 --> 00:05:02,450
which now guarantees that, in places that use values of type Meters,
83
00:05:02,880 --> 00:05:03,999
we can't use a plain
84
00:05:04,000 --> 00:05:04,550
u8.
85
00:05:05,440 --> 00:05:10,550
If we try to compile this code that attempts to call a function that takes Meters with a plain u8,
86
00:05:11,140 --> 00:05:12,150
we'll get a type error.
87
00:05:13,180 --> 00:05:17,450
This can prevent bugs caused by accidentally using values that are in the wrong units.
88
00:05:19,770 --> 00:05:23,919
Structs actually don't need to have any fields. Structs without
89
00:05:23,920 --> 00:05:25,139
fields are called unit
90
00:05:25,140 --> 00:05:25,650
structs.
91
00:05:26,940 --> 00:05:27,279
Unit
92
00:05:27,280 --> 00:05:29,150
structs don't seem very useful yet,
93
00:05:29,810 --> 00:05:31,370
but you can define methods on them.
94
00:05:32,140 --> 00:05:34,250
We're going to talk about methods in the next module.
95
00:05:36,400 --> 00:05:37,250
One last thing:
96
00:05:38,340 --> 00:05:40,950
now that we've seen what structs with named fields look like,
97
00:05:41,440 --> 00:05:42,139
let's look at
98
00:05:42,140 --> 00:05:44,850
enum variants that can have named fields like structs.
99
00:05:46,990 --> 00:05:49,290
Remember the clock example from the last module?
100
00:05:50,240 --> 00:05:52,760
Each variant held values representing hours,
101
00:05:52,770 --> 00:05:54,080
minutes, or seconds.
102
00:05:54,690 --> 00:05:57,450
But it was hard to tell which field meant which value - you just had to know.
103
00:05:57,840 --> 00:06:04,410
We can make this better by making these variants more like a struct and adding field names.
104
00:06:05,440 --> 00:06:08,050
We also have to change the parentheses to curly brackets.
105
00:06:10,140 --> 00:06:11,800
In this module, we covered
106
00:06:11,810 --> 00:06:13,650
when to use structs versus enums,
107
00:06:14,100 --> 00:06:17,319
how to declare and use structs, tuple and unit
108
00:06:17,320 --> 00:06:19,350
structs, and enum variants
109
00:06:19,360 --> 00:06:20,420
that look like structs.
110
00:06:21,740 --> 00:06:23,350
That's how structs work in Rust.
111
00:06:24,140 --> 00:06:26,910
Go forth and organize your data into new types.
112
00:06:28,240 --> 00:06:28,720
Next,
113
00:06:28,730 --> 00:06:32,750
we'll talk about adding behavior to structs and enums by defining methods on them.