1 00:00:06,600 --> 00:00:09,030 - Rust allows you to define structure types 2 00:00:09,030 --> 00:00:10,740 or structs as they're known. 3 00:00:10,740 --> 00:00:13,920 In a structure, you can define related fields, 4 00:00:13,920 --> 00:00:15,810 and related functionality, 5 00:00:15,810 --> 00:00:18,540 and also you can implement traits. 6 00:00:18,540 --> 00:00:21,570 Remember in Rust, a trait is like an interface. 7 00:00:21,570 --> 00:00:23,040 So, this would be equivalent 8 00:00:23,040 --> 00:00:26,100 to some of the concepts of classes in other languages. 9 00:00:26,100 --> 00:00:30,540 In other languages, like Java and C Sharp, C++ and Python, 10 00:00:30,540 --> 00:00:32,043 you can define classes. 11 00:00:32,970 --> 00:00:35,910 In Rust, they're called structures. 12 00:00:35,910 --> 00:00:38,130 In Rust, we have traits, 13 00:00:38,130 --> 00:00:40,140 in other languages, we have interfaces. 14 00:00:40,140 --> 00:00:42,960 So, the concepts are quite similar in Rust 15 00:00:42,960 --> 00:00:45,450 but the terminology and the syntax is different 16 00:00:45,450 --> 00:00:47,880 probably from what you're gonna be familiar with 17 00:00:47,880 --> 00:00:49,680 in those other languages. 18 00:00:49,680 --> 00:00:51,420 So, to define a structure type, 19 00:00:51,420 --> 00:00:53,280 you use the struct keyword, 20 00:00:53,280 --> 00:00:54,960 you give your structure type a name, 21 00:00:54,960 --> 00:00:56,340 starting with capital letter. 22 00:00:56,340 --> 00:00:58,530 Rust is quite fussy about that. 23 00:00:58,530 --> 00:01:01,560 And then you define the field names and types. 24 00:01:01,560 --> 00:01:04,770 You can also define functionality for structure, 25 00:01:04,770 --> 00:01:07,050 like you could for a class in other languages. 26 00:01:07,050 --> 00:01:10,110 We'll have a look at that in the next lesson. 27 00:01:10,110 --> 00:01:11,610 Right. Here's a simple example. 28 00:01:11,610 --> 00:01:13,950 I've defined a structure type called Employee. 29 00:01:13,950 --> 00:01:15,870 An Employee has a field called name, 30 00:01:15,870 --> 00:01:19,470 which is a string, salary is an unsigned 64. 31 00:01:19,470 --> 00:01:21,390 That's ambitious, isn't it? 32 00:01:21,390 --> 00:01:24,150 And then a fulltime boolean field as well. 33 00:01:24,150 --> 00:01:26,460 I haven't actually created any objects yet, 34 00:01:26,460 --> 00:01:29,553 I've just defined the shape of the structure in memory. 35 00:01:30,780 --> 00:01:34,830 Now, by default, a structure and its fields are private. 36 00:01:34,830 --> 00:01:38,010 You can only access the structure and its fields 37 00:01:38,010 --> 00:01:41,670 within the module, within the file they're defined. 38 00:01:41,670 --> 00:01:43,050 Okay. And that might be fine, 39 00:01:43,050 --> 00:01:45,750 but if you want a structure to be accessed elsewhere, 40 00:01:45,750 --> 00:01:47,340 then you have to marked it as public. 41 00:01:47,340 --> 00:01:50,760 You have to use the pub keyword on the structure type. 42 00:01:50,760 --> 00:01:52,290 You also have to do that with the fields. 43 00:01:52,290 --> 00:01:53,970 If you want the fields to be public, 44 00:01:53,970 --> 00:01:56,760 then you have to say pub on each field as well. 45 00:01:56,760 --> 00:01:59,733 Otherwise, the fields would be private just to that file. 46 00:02:00,750 --> 00:02:04,170 Now, it's quite common to put a structure 47 00:02:04,170 --> 00:02:07,950 into a separate module file, so it can then be reused 48 00:02:07,950 --> 00:02:09,360 across the entire application. 49 00:02:09,360 --> 00:02:11,250 So that's what we are going to do. 50 00:02:11,250 --> 00:02:15,120 In order for that structure to be visible outside that file, 51 00:02:15,120 --> 00:02:16,620 we'd have to make it public. 52 00:02:16,620 --> 00:02:17,460 And I'm gonna do that. 53 00:02:17,460 --> 00:02:20,460 They're gonna have a public structure and public fields, 54 00:02:20,460 --> 00:02:24,480 and I'm gonna put it into a separate file called mytypes.rs. 55 00:02:24,480 --> 00:02:26,640 You can call the file anything you want, okay? 56 00:02:26,640 --> 00:02:28,140 It's not like Java, 57 00:02:28,140 --> 00:02:31,650 where you have to have a file name called employee.java. 58 00:02:31,650 --> 00:02:33,150 You can call it anything you want to, 59 00:02:33,150 --> 00:02:35,370 and you can have as many structure types as you want 60 00:02:35,370 --> 00:02:36,510 in a given file. 61 00:02:36,510 --> 00:02:40,830 So mytypes.rs, it defines a public structure Employee 62 00:02:40,830 --> 00:02:42,870 with public fields. 63 00:02:42,870 --> 00:02:44,400 At the moment, it's just a file. 64 00:02:44,400 --> 00:02:47,610 In order to introduce that file as a module 65 00:02:47,610 --> 00:02:50,580 in your application, then in main.rs, 66 00:02:50,580 --> 00:02:52,770 you'd have to declare it as a module. 67 00:02:52,770 --> 00:02:55,080 Okay? So remember this is important. 68 00:02:55,080 --> 00:02:58,833 We need to declare a module in Rust called mytpes. 69 00:02:59,910 --> 00:03:04,590 It will go and look for a file called mytypes.rs 70 00:03:04,590 --> 00:03:06,780 in the current folder by default. 71 00:03:06,780 --> 00:03:09,900 And it'll drag that code and effectively input that code 72 00:03:09,900 --> 00:03:11,280 into your application. 73 00:03:11,280 --> 00:03:14,190 If you forgot to say mod mytypes, 74 00:03:14,190 --> 00:03:16,590 the compiler would completely ignore this file 75 00:03:16,590 --> 00:03:19,140 and it wouldn't be part of your code base. 76 00:03:19,140 --> 00:03:22,290 So, don't forget to declare the module 77 00:03:22,290 --> 00:03:26,910 to effectively import the code into your application. 78 00:03:26,910 --> 00:03:28,110 So, let's say we've done that. 79 00:03:28,110 --> 00:03:30,600 Let's say, we declared the module mytypes 80 00:03:30,600 --> 00:03:33,180 and I want to actually create an employee object. 81 00:03:33,180 --> 00:03:37,140 Well, you could use fully qualified syntax like this. 82 00:03:37,140 --> 00:03:38,970 We haven't seen the syntax before. 83 00:03:38,970 --> 00:03:40,890 So let me explain. 84 00:03:40,890 --> 00:03:43,800 Effectively in Rust, you have kind of like a module, 85 00:03:43,800 --> 00:03:47,433 a hierarchy, whenever your project might be called, 86 00:03:48,360 --> 00:03:52,470 there's a logical namespace at the top called crate, okay? 87 00:03:52,470 --> 00:03:56,190 That represents the root namespace in your project. 88 00:03:56,190 --> 00:04:00,360 And then for each module, each module or submodule 89 00:04:00,360 --> 00:04:01,950 is considered to be like a child. 90 00:04:01,950 --> 00:04:04,623 So we have a hierarchy of names, mytypes, 91 00:04:06,496 --> 00:04:11,370 and in mytypes, I've defined a structure called Employee. 92 00:04:13,582 --> 00:04:16,380 Okay? So in anywhere in your application, 93 00:04:16,380 --> 00:04:18,330 if you want to use the Employee structure, 94 00:04:18,330 --> 00:04:21,630 you could say effectively crate is a keyword, 95 00:04:21,630 --> 00:04:23,643 go to the root of my namespace, 96 00:04:24,660 --> 00:04:27,843 here, underneath go to the submodule called mytypes, 97 00:04:29,310 --> 00:04:30,270 which is here. 98 00:04:30,270 --> 00:04:33,690 And then in there, you'll find the Employee structure type, 99 00:04:33,690 --> 00:04:34,523 which is there. 100 00:04:34,523 --> 00:04:36,330 So that's a fully qualified syntax. 101 00:04:36,330 --> 00:04:38,550 You could use the syntax anywhere 102 00:04:38,550 --> 00:04:41,460 you wanted to use Employee in your application. 103 00:04:41,460 --> 00:04:42,750 It would get quite tiresome though, 104 00:04:42,750 --> 00:04:44,520 have to say crate, colon, colon, 105 00:04:44,520 --> 00:04:46,920 mytypes, colon, colon, employee. 106 00:04:46,920 --> 00:04:49,230 Simpler approach that people usually go for, 107 00:04:49,230 --> 00:04:51,630 is to use the used statement. 108 00:04:51,630 --> 00:04:52,830 Remember, what the used statement does, 109 00:04:52,830 --> 00:04:55,170 it just brings something into scope, okay? 110 00:04:55,170 --> 00:04:58,140 So the Employee structure type already exists. 111 00:04:58,140 --> 00:05:01,020 All you're doing is introducing it into the current scope. 112 00:05:01,020 --> 00:05:04,200 So, when you say use crate mytypes Employee, 113 00:05:04,200 --> 00:05:06,240 it means you can then use this symbol name 114 00:05:06,240 --> 00:05:08,910 directly in your application rather than 115 00:05:08,910 --> 00:05:12,243 have to use the fully qualified name like we did before. 116 00:05:13,530 --> 00:05:15,390 Okay. Right. 117 00:05:15,390 --> 00:05:17,310 Well, we'll have a look at an example. 118 00:05:17,310 --> 00:05:19,262 For this lesson, the project is 119 00:05:19,262 --> 00:05:20,912 lesson10_structs_getting_started. 120 00:05:22,110 --> 00:05:24,630 Let me just quickly show you that. 121 00:05:24,630 --> 00:05:27,146 All right, so in the rustdev demos folder, 122 00:05:27,146 --> 00:05:29,910 lesson10_structs_getting_started. 123 00:05:29,910 --> 00:05:34,050 So, if you open that project in code editor, 124 00:05:34,050 --> 00:05:35,460 and here we are, the files 125 00:05:35,460 --> 00:05:37,860 that we're going to look at up here are. 126 00:05:37,860 --> 00:05:41,640 Well, first of all mytypes.rs as advertised, 127 00:05:41,640 --> 00:05:44,280 it defines a public structure called Employee 128 00:05:44,280 --> 00:05:46,200 with public fields. 129 00:05:46,200 --> 00:05:47,703 And then in the main code, 130 00:05:49,230 --> 00:05:53,280 I declare it as a module, 131 00:05:53,280 --> 00:05:54,420 technically that's how you'd say it. 132 00:05:54,420 --> 00:05:56,310 I declare it as a module that causes 133 00:05:56,310 --> 00:05:59,130 that file to be processed. 134 00:05:59,130 --> 00:06:01,260 I've got some other modules as well. 135 00:06:01,260 --> 00:06:03,972 Each of these other modules is illustrating 136 00:06:03,972 --> 00:06:08,160 different techniques per section in the lesson. 137 00:06:08,160 --> 00:06:11,850 So, as well as importing the mytypes module 138 00:06:11,850 --> 00:06:13,980 which has got my Employee structure. 139 00:06:13,980 --> 00:06:16,730 I've also imported, for example, demo_accessing_struct. 140 00:06:18,090 --> 00:06:20,313 And that's here. 141 00:06:21,900 --> 00:06:24,330 And in this example, 142 00:06:24,330 --> 00:06:29,330 I've imported from the top level namespace in my crate. 143 00:06:30,210 --> 00:06:32,130 I've imported the mytypes module. 144 00:06:32,130 --> 00:06:34,533 I've imported the Employee structure name. 145 00:06:35,460 --> 00:06:37,890 Okay. I could still use the fully qualified name 146 00:06:37,890 --> 00:06:38,760 if I want to. 147 00:06:38,760 --> 00:06:40,350 I've declared a variable here called e1. 148 00:06:40,350 --> 00:06:42,030 Notice the underscore because I'm not actually 149 00:06:42,030 --> 00:06:43,500 gonna be using the variable just yet. 150 00:06:43,500 --> 00:06:45,150 So, I've got an underscore here 151 00:06:45,150 --> 00:06:48,450 to avoid getting compiler warnings. 152 00:06:48,450 --> 00:06:52,020 Anyway, e1 is off type crate, colon, colon, 153 00:06:52,020 --> 00:06:54,570 mytypes, colon, colon, Employee, right? 154 00:06:54,570 --> 00:06:59,100 So that would've worked, even if I hadn't imported the name. 155 00:06:59,100 --> 00:07:01,470 But since as I have imported the name Employee, 156 00:07:01,470 --> 00:07:04,170 I could just use the employee name directly, 157 00:07:04,170 --> 00:07:06,090 and of course that would be a much better approach. 158 00:07:06,090 --> 00:07:08,820 So, really here I wouldn't bother 159 00:07:08,820 --> 00:07:10,110 using the fully qualified name, 160 00:07:10,110 --> 00:07:12,600 I would just declare that as an Employee as well. 161 00:07:12,600 --> 00:07:15,360 I was just put in there just to remind you. 162 00:07:15,360 --> 00:07:16,350 Wouldn't it be interesting to see 163 00:07:16,350 --> 00:07:19,350 how many bytes an Employee object would take? 164 00:07:19,350 --> 00:07:22,440 Well, in the standard crate, there's the mem module, 165 00:07:22,440 --> 00:07:25,170 which has a size of function, which is generic, 166 00:07:25,170 --> 00:07:26,160 you can give it a type 167 00:07:26,160 --> 00:07:29,640 and it'll tell you how many bytes that type is, 168 00:07:29,640 --> 00:07:31,440 what's the size of that type in bytes. 169 00:07:31,440 --> 00:07:33,870 So, I thought it would be quite interesting to see. 170 00:07:33,870 --> 00:07:35,640 Right. Well, in my main code, 171 00:07:35,640 --> 00:07:38,850 let me just run the demo_accessing_instruct. 172 00:07:38,850 --> 00:07:40,260 That's the code we just saw 173 00:07:40,260 --> 00:07:43,260 and it'll tell us how big the structure type is in memory. 174 00:07:43,260 --> 00:07:45,090 We haven't actually created any instances yet, 175 00:07:45,090 --> 00:07:48,780 but in theory, how big is the structure type itself? 176 00:07:48,780 --> 00:07:49,613 Cargo run. 177 00:07:53,760 --> 00:07:56,460 So, it turns out the size of a structure of an Employee 178 00:07:56,460 --> 00:07:59,310 is 40 bytes. 179 00:07:59,310 --> 00:08:01,083 Okay. So, 180 00:08:02,850 --> 00:08:06,390 a u64 is eight bytes. 181 00:08:06,390 --> 00:08:10,530 A boolean is probably one or two bytes. 182 00:08:10,530 --> 00:08:13,290 A string is probably about 24 bytes, I think. 183 00:08:13,290 --> 00:08:14,700 So, there's pretty some alignment in there, 184 00:08:14,700 --> 00:08:16,650 just to make the fields align nicely. 185 00:08:16,650 --> 00:08:18,840 But anyway, it tells me one of those 186 00:08:18,840 --> 00:08:21,240 will be 40 bytes in size. 187 00:08:21,240 --> 00:08:24,000 So, we've seen how to define structured types, 188 00:08:24,000 --> 00:08:26,640 and basically how to organize it into separate modules. 189 00:08:26,640 --> 00:08:28,380 What we're gonna see in the next demo 190 00:08:28,380 --> 00:08:30,690 is how to actually create employees 191 00:08:30,690 --> 00:08:33,290 and actually start accessing the fields inside them.