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.