1 00:00:00,000 --> 00:00:08,000 [No Audio] 2 00:00:08,001 --> 00:00:10,400 A structure creates a data type that can be 3 00:00:10,401 --> 00:00:12,566 used to group items of possibly different 4 00:00:12,567 --> 00:00:15,566 types into a single type. A structure is used 5 00:00:15,567 --> 00:00:17,933 to represent information about something more 6 00:00:17,934 --> 00:00:20,066 complicated than a single number, character, 7 00:00:20,067 --> 00:00:23,066 or Boolean, and even more complicated than an 8 00:00:23,100 --> 00:00:25,866 array or vector of the above data types. For 9 00:00:25,867 --> 00:00:28,800 example, a student can be defined by his or 10 00:00:28,801 --> 00:00:33,433 her name, GPA, age, user Id, etc. Each 11 00:00:33,434 --> 00:00:35,166 of these pieces of information should be 12 00:00:35,167 --> 00:00:37,433 labeled with an easily understood descriptive 13 00:00:37,434 --> 00:00:39,866 title, and then combined to form a whole which 14 00:00:39,867 --> 00:00:42,100 is referred to as what we call a structure. 15 00:00:42,733 --> 00:00:44,733 Pretty much exciting material is coming our 16 00:00:44,734 --> 00:00:46,433 way, so let's dive into it. 17 00:00:47,833 --> 00:00:50,533 The very first thing about structure is, how to define or 18 00:00:50,534 --> 00:00:53,200 declare a structure? For declaration, the 19 00:00:53,201 --> 00:00:55,900 reserved word of struct will be used followed 20 00:00:55,901 --> 00:00:58,600 by the name of the struct. Please note that, 21 00:00:58,601 --> 00:01:00,433 in Rust, the convention for the names of the 22 00:01:00,434 --> 00:01:03,500 struct is that of camel case. There are no 23 00:01:03,501 --> 00:01:05,500 spaces between the individual words and the 24 00:01:05,501 --> 00:01:08,100 first letter of each word, of the name starts 25 00:01:08,101 --> 00:01:10,166 with a capital letter followed by lowercase 26 00:01:10,167 --> 00:01:13,033 characters. Let us define a struct called 27 00:01:13,034 --> 00:01:15,000 Person, which will be used to store the 28 00:01:15,001 --> 00:01:17,366 general information about a person such as 29 00:01:17,367 --> 00:01:20,100 his citizenship information, name, age, 30 00:01:20,101 --> 00:01:23,366 gender and salary. Inside the body of the 31 00:01:23,367 --> 00:01:25,133 structure, we will declare the names of the 32 00:01:25,134 --> 00:01:27,233 fields of the structure along with their types. 33 00:01:27,833 --> 00:01:29,600 The fields can be of different types, 34 00:01:29,601 --> 00:01:31,914 and we can have as many fields as we may like. 35 00:01:31,915 --> 00:01:40,700 [No Audio] 36 00:01:40,701 --> 00:01:42,366 The structure will be typically defined 37 00:01:42,367 --> 00:01:44,466 outside the body of the main function. Now, 38 00:01:44,467 --> 00:01:46,666 let us use the structure inside our main 39 00:01:46,667 --> 00:01:49,633 function. To declare an instance of this 40 00:01:49,634 --> 00:01:51,766 structure or an element of type Person, we 41 00:01:51,767 --> 00:01:53,800 will use the lat, and then name of the 42 00:01:53,801 --> 00:01:56,633 variable which we want to have for instance person1. 43 00:01:56,634 --> 00:01:59,466 [No Audio] 44 00:01:59,467 --> 00:02:01,833 This means now that the variable person1 45 00:02:01,834 --> 00:02:03,266 is of type Person, which is a structure. 46 00:02:04,866 --> 00:02:06,600 Next we will define values for the 47 00:02:06,601 --> 00:02:08,699 individual fields, by writing values for all 48 00:02:08,700 --> 00:02:11,166 the fields one by one. I will use my Person 49 00:02:11,167 --> 00:02:12,766 information in this case. 50 00:02:12,767 --> 00:02:17,900 [No Audio] 51 00:02:17,901 --> 00:02:20,000 Please note that since this is an assignment 52 00:02:20,300 --> 00:02:22,066 to a variable, therefore, the body of the 53 00:02:22,067 --> 00:02:24,166 code segment should end with a semicolon. 54 00:02:24,500 --> 00:02:26,633 Moreover, it is not necessary to match the 55 00:02:26,634 --> 00:02:28,600 order in which the fields are defined inside 56 00:02:28,601 --> 00:02:31,200 the structure definition. Okay, great so far, 57 00:02:31,600 --> 00:02:33,100 to access the individual fields of the 58 00:02:33,101 --> 00:02:34,566 structure, we will use the name of the 59 00:02:34,567 --> 00:02:36,766 structure variable followed by a dot and then 60 00:02:36,767 --> 00:02:39,166 the name of the field. Let us display the 61 00:02:39,167 --> 00:02:42,166 values of the of some of the fields of person1. 62 00:02:42,171 --> 00:02:48,800 [No Audio] 63 00:02:48,801 --> 00:02:50,253 Let us cargo run to check. 64 00:02:50,254 --> 00:02:55,633 [No Audio] 65 00:02:55,634 --> 00:02:58,200 Now once the data is being organized in 66 00:02:58,201 --> 00:03:00,533 the form of structures, we can define 67 00:03:00,534 --> 00:03:02,766 functions which operates on the instances of 68 00:03:02,767 --> 00:03:05,633 specific structures. To better organize the 69 00:03:05,634 --> 00:03:07,866 functions, that we may define in the context 70 00:03:07,867 --> 00:03:10,434 of a specific structure. The Rust 71 00:03:10,435 --> 00:03:13,166 provides an implementation block for the structures. 72 00:03:14,233 --> 00:03:16,966 Let us define compute_taxes function 73 00:03:16,967 --> 00:03:19,633 for the Person structure, 74 00:03:19,634 --> 00:03:21,866 I will do it inside an implementation block. To 75 00:03:21,867 --> 00:03:24,033 have an implementation block for a 76 00:03:24,034 --> 00:03:26,000 structure, we will use the impl keyword 77 00:03:26,001 --> 00:03:27,558 followed by the name of the structure. 78 00:03:27,559 --> 00:03:32,433 [No Audio] 79 00:03:32,434 --> 00:03:34,700 This is called an implementation of the structure, 80 00:03:34,701 --> 00:03:36,500 which is nothing but the code block which 81 00:03:36,501 --> 00:03:38,800 contains the relevant functions that we can 82 00:03:38,801 --> 00:03:41,633 have for the respective structure. Please 83 00:03:41,634 --> 00:03:44,133 note that, we do not frequently use the word 84 00:03:44,134 --> 00:03:46,200 of variable when referring to an instance of 85 00:03:46,201 --> 00:03:48,166 the structure, but rather we call it as an 86 00:03:48,167 --> 00:03:49,626 object or an instance of the structure. 87 00:03:49,627 --> 00:03:51,400 [No Audio] 88 00:03:51,401 --> 00:03:54,643 Let us have a compute_taxes function now. 89 00:03:54,644 --> 00:03:58,033 [No Audio] 90 00:03:58,034 --> 00:03:59,666 This function will take a reference to 91 00:03:59,667 --> 00:04:01,600 the structure instance which is calling it, 92 00:04:01,601 --> 00:04:03,933 and then it will return an f32 value, which 93 00:04:03,934 --> 00:04:06,000 will be the value of the taxes that is 94 00:04:06,001 --> 00:04:08,766 applicable on the person. To mention at the 95 00:04:08,767 --> 00:04:10,900 reference of a structure object or instance, 96 00:04:10,901 --> 00:04:14,433 which is calling this function, I will write &self. 97 00:04:16,033 --> 00:04:17,065 This basically means 98 00:04:17,066 --> 00:04:19,166 a reference to the calling structure instance, 99 00:04:19,167 --> 00:04:21,433 for which we can call this function. 100 00:04:21,800 --> 00:04:23,800 Inside the body of the function, I will write some 101 00:04:23,801 --> 00:04:29,000 formula, such as self.salary as f32/ 3 times 0.5. 102 00:04:29,001 --> 00:04:31,566 [No Audio] 103 00:04:31,567 --> 00:04:32,633 And I will not include 104 00:04:32,634 --> 00:04:34,466 any semicolon to indicate that this 105 00:04:34,467 --> 00:04:37,166 is a returning value. Please note that, the 106 00:04:37,167 --> 00:04:39,633 self followed by a dot, can be used to refer 107 00:04:39,634 --> 00:04:41,666 to the individual fields of the structure, for 108 00:04:41,667 --> 00:04:44,066 which we are calling this function. Let us 109 00:04:44,067 --> 00:04:45,466 call this function from the main. 110 00:04:46,566 --> 00:04:49,633 I will call it inside a print statement by calling it 111 00:04:49,634 --> 00:04:51,866 for the instance of person1. 112 00:04:51,867 --> 00:04:56,900 [No Audio] 113 00:04:56,901 --> 00:04:58,500 In this case, now the person1 will be 114 00:04:58,501 --> 00:05:01,100 passed as a reference to the function, and in 115 00:05:01,101 --> 00:05:03,633 the &self inside the function means a 116 00:05:03,634 --> 00:05:05,933 reference to person1 . Please note that, 117 00:05:05,966 --> 00:05:08,133 under the fn compute_taxes 118 00:05:08,134 --> 00:05:11,300 requires an explicit input, however, with the 119 00:05:11,301 --> 00:05:13,333 .syntax, the difference is passed by 120 00:05:13,334 --> 00:05:16,733 default, and we do not need to mention it explicitly. 121 00:05:16,833 --> 00:05:18,300 Let us note that, the function is 122 00:05:18,301 --> 00:05:20,366 being called for person1, and therefore, 123 00:05:20,367 --> 00:05:23,233 we do not need to mention it again, let us cargo run this. 124 00:05:23,234 --> 00:05:28,066 [No Audio] 125 00:05:28,067 --> 00:05:29,666 We may note that, the taxes value 126 00:05:29,667 --> 00:05:32,033 has been computed correctly. Okay please 127 00:05:32,034 --> 00:05:34,800 note that, in order to access the compute_taxes, 128 00:05:34,801 --> 00:05:37,200 we are required to use the dot notation, 129 00:05:37,201 --> 00:05:39,900 it let the compiler knows which 130 00:05:39,901 --> 00:05:42,600 particular function I am referring to. In case 131 00:05:42,601 --> 00:05:45,133 I do not use the dot notation, then in that 132 00:05:45,134 --> 00:05:49,200 case I will write something like person::compute_taxes. 133 00:05:49,700 --> 00:05:53,933 The double colon syntax kind of tells the Rust compiler 134 00:05:53,934 --> 00:05:56,333 where to look for the function. In this case 135 00:05:56,334 --> 00:05:58,200 now, we will be required to explicitly 136 00:05:58,201 --> 00:06:00,000 mention the inputs to the function, because 137 00:06:00,001 --> 00:06:01,866 the compiler is unable to know for which 138 00:06:01,867 --> 00:06:04,266 instance of the person you want to call this 139 00:06:04,267 --> 00:06:06,633 function. So, I will write something like 140 00:06:06,634 --> 00:06:09,966 &person1, which will pass a reference to the 141 00:06:09,967 --> 00:06:12,966 function for person1. This will have 142 00:06:12,967 --> 00:06:16,533 exactly the same effect as person1.compute_taxes. 143 00:06:16,833 --> 00:06:18,463 Let us execute to confirm this. 144 00:06:18,464 --> 00:06:24,500 [No Audio] 145 00:06:24,501 --> 00:06:26,766 I will however, prefer the style of writing it 146 00:06:26,767 --> 00:06:29,900 in the form of person1.compute_taxes. 147 00:06:29,901 --> 00:06:31,166 In summary, with the double 148 00:06:31,167 --> 00:06:33,700 colon, the function is available to the type 149 00:06:33,701 --> 00:06:36,166 itself, that is the type Person, which we 150 00:06:36,167 --> 00:06:38,400 mentioned before the double colon. With the dot, 151 00:06:38,401 --> 00:06:40,633 we perform some operation or functions such as 152 00:06:40,634 --> 00:06:42,800 reading, writing, processing, or updating the 153 00:06:42,801 --> 00:06:45,366 data of the specific type of instance. 154 00:06:45,966 --> 00:06:48,266 The double colon has another advantage which 155 00:06:48,267 --> 00:06:50,333 will become evident to us, once we cover the 156 00:06:50,334 --> 00:06:53,966 module system of Rust. Sometimes, it is very 157 00:06:53,967 --> 00:06:56,733 useful to have an initializing function to 158 00:06:56,734 --> 00:06:58,766 initialize the value of a new structure 159 00:06:58,767 --> 00:07:01,933 instance from some default values. This helps 160 00:07:01,934 --> 00:07:03,666 in reducing some codebook and quick 161 00:07:03,667 --> 00:07:06,000 initialization of new structure instances. 162 00:07:06,066 --> 00:07:08,134 For instance, if I want to declare 10 new 163 00:07:08,135 --> 00:07:10,933 instances, 10 new structure instances, then 164 00:07:10,934 --> 00:07:12,766 I will have to write the code something like 165 00:07:12,767 --> 00:07:15,566 the code above 10 times. Instead, I would 166 00:07:15,567 --> 00:07:17,366 like to deduce the code, and we'll 167 00:07:17,367 --> 00:07:19,500 initialize the structure fields from some 168 00:07:19,501 --> 00:07:22,000 useful defaults, which I may later on update. 169 00:07:22,900 --> 00:07:25,033 The initialization function is typically 170 00:07:25,034 --> 00:07:28,033 named as a new function. You may 171 00:07:28,034 --> 00:07:30,200 name it as you want such as initializing 172 00:07:30,201 --> 00:07:32,566 function, or whatever, the convention however 173 00:07:32,567 --> 00:07:35,800 is to call it new. This function will also be 174 00:07:35,801 --> 00:07:37,533 added to the implementation block of the 175 00:07:37,534 --> 00:07:38,977 structure. Let me add this. 176 00:07:38,978 --> 00:07:42,966 [No Audio] 177 00:07:42,967 --> 00:07:45,400 This function will return a structure instance. 178 00:07:45,401 --> 00:07:47,200 So, instead of having a reference 179 00:07:47,201 --> 00:07:48,666 which is specified above 180 00:07:48,667 --> 00:07:51,066 by mentioning &self, I will mention the 181 00:07:51,067 --> 00:07:53,566 structure that I create here by writing Self 182 00:07:53,567 --> 00:07:56,533 with a capital S. The Self with a capital S 183 00:07:56,534 --> 00:07:59,100 inside the implementation block refers to the 184 00:07:59,101 --> 00:08:02,233 structure type itself, which is the Person itself. 185 00:08:02,600 --> 00:08:04,500 This means that this function will 186 00:08:04,501 --> 00:08:06,700 return a structure of type person, since it is 187 00:08:06,701 --> 00:08:08,500 defined inside the Person structure 188 00:08:08,501 --> 00:08:11,400 implementation block. Next, I will add the 189 00:08:11,401 --> 00:08:13,433 body of the function. I will define the 190 00:08:13,434 --> 00:08:15,900 structure of a Person with some default 191 00:08:15,901 --> 00:08:17,400 values for its fields. 192 00:08:17,401 --> 00:08:26,766 [No Audio] 193 00:08:26,767 --> 00:08:28,733 We may now call this function from the main 194 00:08:28,734 --> 00:08:30,866 to create new instances of the type Person. 195 00:08:31,000 --> 00:08:33,166 Let us create one with the name of person2 196 00:08:33,167 --> 00:08:34,966 and we'll assign it to the returning value 197 00:08:34,967 --> 00:08:36,200 from the new function. 198 00:08:36,201 --> 00:08:42,166 [No Audio] 199 00:08:42,167 --> 00:08:43,633 Let us now check if the function has 200 00:08:43,634 --> 00:08:45,566 successfully created a new instance by 201 00:08:45,567 --> 00:08:47,143 displaying some of the fields. 202 00:08:47,144 --> 00:08:52,833 [No Audio] 203 00:08:52,834 --> 00:08:54,100 Let us execute now. 204 00:08:54,101 --> 00:08:58,133 [No Audio] 205 00:08:58,134 --> 00:09:00,700 person2 has been successfully initialized from 206 00:09:00,701 --> 00:09:04,600 proper default values. Please note that, inside the new 207 00:09:04,601 --> 00:09:07,600 function we may write instead of Self Person, 208 00:09:07,712 --> 00:09:11,000 because we have the same meaning within this context. 209 00:09:11,233 --> 00:09:12,900 Similarly, for the person inside the 210 00:09:12,901 --> 00:09:15,100 body of the function we may also write Self 211 00:09:15,200 --> 00:09:17,733 instead of Person, because Person and Self 212 00:09:17,734 --> 00:09:19,466 have the same meaning inside the 213 00:09:19,467 --> 00:09:21,800 implementation block. In general, inside the 214 00:09:21,801 --> 00:09:23,900 implementation block of a structure the Self 215 00:09:23,901 --> 00:09:26,233 is referring to the structure type itself. 216 00:09:27,466 --> 00:09:29,400 The Rust provides another useful way for 217 00:09:29,401 --> 00:09:31,533 quickly initializing a structure from the 218 00:09:31,534 --> 00:09:34,466 values of some other already existing structures. 219 00:09:35,466 --> 00:09:36,800 Suppose we want to have another 220 00:09:36,801 --> 00:09:38,900 instance of the structure such as person3, 221 00:09:38,901 --> 00:09:40,700 and I want to just update its age and 222 00:09:40,701 --> 00:09:42,766 name, and the remaining fields should be the 223 00:09:42,767 --> 00:09:44,966 same as that of person1. So I will just 224 00:09:44,967 --> 00:09:47,266 update and mentioned the values for the age and name. 225 00:09:47,267 --> 00:09:49,600 [No Audio] 226 00:09:49,601 --> 00:09:51,666 And we'll have a couple of dots, and 227 00:09:51,667 --> 00:09:54,000 after that the name of the structure instance 228 00:09:54,001 --> 00:09:57,366 person1 from a where the remaining values 229 00:09:57,367 --> 00:10:01,100 will be initialized from. Let us print 230 00:10:01,101 --> 00:10:02,666 some of the fields of person3 and 231 00:10:02,667 --> 00:10:04,071 execute to see the values. 232 00:10:04,072 --> 00:10:11,366 [No Audio] 233 00:10:11,367 --> 00:10:13,433 All these structure instances that we have 234 00:10:13,434 --> 00:10:16,300 created so far were immutable. This means 235 00:10:16,301 --> 00:10:18,900 that their values cannot be changed once 236 00:10:18,901 --> 00:10:21,500 assigned to them just like immutable variables. 237 00:10:21,766 --> 00:10:23,500 Let us create a new immutable 238 00:10:23,501 --> 00:10:26,533 structure of person4 and display some of its values. 239 00:10:26,534 --> 00:10:35,166 [No Audio] 240 00:10:35,167 --> 00:10:37,333 Let us see if we can now update some of its 241 00:10:37,334 --> 00:10:40,100 values, I will update the name and print the value. 242 00:10:40,101 --> 00:10:47,633 [No Audio] 243 00:10:47,634 --> 00:10:49,066 Let us execute. 244 00:10:49,067 --> 00:10:55,233 [No Audio] 245 00:10:55,234 --> 00:10:57,033 We may note that, the field value has been 246 00:10:57,034 --> 00:11:00,700 updated from the default value. Okay now, let 247 00:11:00,701 --> 00:11:02,933 us move to another topic called tuple structure. 248 00:11:02,936 --> 00:11:12,100 [No Audio] 249 00:11:12,101 --> 00:11:14,533 A Tuple Struct is very similar to that of a tuple, 250 00:11:14,534 --> 00:11:16,700 but with a key difference, that we have 251 00:11:16,701 --> 00:11:19,733 a name of the tuple also. Simple tuples do 252 00:11:19,734 --> 00:11:23,133 not have an associated name, while the tuple 253 00:11:23,134 --> 00:11:25,800 structs have an associated name. Unlike 254 00:11:25,801 --> 00:11:27,566 typical structures, the tuple structs will 255 00:11:27,567 --> 00:11:29,866 not have a names associated with its 256 00:11:29,867 --> 00:11:31,833 individual fields, and therefore, they are 257 00:11:31,834 --> 00:11:34,200 referred to as tuples structures since tuples 258 00:11:34,201 --> 00:11:36,833 also have no names for its individual fields. 259 00:11:37,700 --> 00:11:39,634 Things will become more understandable as we 260 00:11:39,635 --> 00:11:42,200 look at an example. Let us create a tuple 261 00:11:42,201 --> 00:11:45,294 struct called Numbers containing a couple of i32 values. 262 00:11:45,295 --> 00:11:52,533 [No Audio] 263 00:11:52,534 --> 00:11:55,233 I can now use it inside the main function. 264 00:11:56,100 --> 00:11:58,400 Let us define an instance of this 265 00:11:58,401 --> 00:11:59,920 with the suitable name. 266 00:11:59,921 --> 00:12:03,233 [No Audio] 267 00:12:03,234 --> 00:12:04,533 Please note that the 268 00:12:04,534 --> 00:12:06,933 fields do not have any names, and we may 269 00:12:06,934 --> 00:12:09,400 therefore access them using their indexes. 270 00:12:09,566 --> 00:12:11,300 Let us add a print statement for displaying 271 00:12:11,301 --> 00:12:12,600 the values of the fields. 272 00:12:12,601 --> 00:12:19,733 [No Audio] 273 00:12:19,734 --> 00:12:21,621 Let us execute to see the result. 274 00:12:21,622 --> 00:12:29,766 [No Audio] 275 00:12:29,767 --> 00:12:31,900 Let us implement some simple functions on 276 00:12:31,901 --> 00:12:34,100 this tuple struct. Remember we need to have 277 00:12:34,101 --> 00:12:36,303 an implementation block first for this purpose. 278 00:12:36,304 --> 00:12:40,500 [No Audio] 279 00:12:40,501 --> 00:12:42,133 I will now add some functions to the 280 00:12:42,134 --> 00:12:45,033 implementation block. I will include a greater 281 00:12:45,034 --> 00:12:46,566 than function which will determine the 282 00:12:46,567 --> 00:12:48,300 greater of the two fields 283 00:12:48,301 --> 00:12:53,900 [No Audio] 284 00:12:53,901 --> 00:12:55,766 Since I am not modifying the values of the 285 00:12:55,767 --> 00:12:57,500 structure, so therefore, I will use a 286 00:12:57,501 --> 00:12:59,766 reference to the structure. Moreover, we use 287 00:12:59,767 --> 00:13:01,666 a dot notation to access the individual 288 00:13:01,667 --> 00:13:04,766 fields of the structure. Let us include one 289 00:13:04,767 --> 00:13:07,033 more simple, a lesser than function which will 290 00:13:07,034 --> 00:13:09,166 have a very similar structure and definition. 291 00:13:09,167 --> 00:13:15,000 [No Audio] 292 00:13:15,001 --> 00:13:16,766 Let us call these functions from the main 293 00:13:16,767 --> 00:13:20,633 function now. I will call it inside a print statement. 294 00:13:20,634 --> 00:13:26,133 [No Audio] 295 00:13:26,134 --> 00:13:27,902 Let us cargo run. 296 00:13:27,903 --> 00:13:32,733 [No Audio] 297 00:13:32,734 --> 00:13:35,400 The result is as expected. With this we end 298 00:13:35,401 --> 00:13:37,366 this tutorial, we have looked at some of the 299 00:13:37,367 --> 00:13:39,433 preliminary details of structure. In the 300 00:13:39,434 --> 00:13:41,266 upcoming tutorial, we will be covering some 301 00:13:41,267 --> 00:13:43,866 advanced topics on structures. So do come 302 00:13:43,867 --> 00:13:45,500 back for covering that, and until then, 303 00:13:45,501 --> 00:13:46,950 happy Rust programming. 304 00:13:46,951 --> 00:13:52,333 [No Audio]