1 00:00:00,000 --> 00:00:07,200 [No Audio] 2 00:00:07,201 --> 00:00:09,280 In this video tutorial, we will be covering 3 00:00:09,281 --> 00:00:12,280 four topics. These topics include scope of a 4 00:00:12,281 --> 00:00:15,400 trait, trait methods with same name, super 5 00:00:15,401 --> 00:00:18,160 traits, marker traits, and auto traits. 6 00:00:18,161 --> 00:00:20,080 Pretty much exciting material to cover, so 7 00:00:20,081 --> 00:00:23,200 let's get started. First, we will talk about 8 00:00:23,201 --> 00:00:25,640 the scope of a trait. The scope of a trait 9 00:00:25,641 --> 00:00:27,800 refers to the portion of the code, where the 10 00:00:27,801 --> 00:00:30,600 trait is visible, and where its methods are 11 00:00:30,601 --> 00:00:33,200 accessible. When a trait is defined in a 12 00:00:33,201 --> 00:00:36,000 module, it is only visible and usable within 13 00:00:36,001 --> 00:00:38,880 that module, and any nested modules within 14 00:00:38,881 --> 00:00:41,240 that particular module. If the trait is 15 00:00:41,241 --> 00:00:45,080 marked as pub, it can, it can also be used by 16 00:00:45,081 --> 00:00:47,320 other modules outside of its scope. 17 00:00:47,720 --> 00:00:49,400 Understanding the scope of a trait is 18 00:00:49,401 --> 00:00:52,200 important for organizing Rust code, and for 19 00:00:52,201 --> 00:00:54,680 ensuring that traits and their methods are 20 00:00:54,681 --> 00:00:57,040 only used where they are intended to be used, 21 00:00:57,041 --> 00:00:59,640 and not accidentally exposed to other parts 22 00:00:59,641 --> 00:01:02,280 of the code where they shouldn't be exposed. 23 00:01:03,280 --> 00:01:05,720 With this background, let us dive into an 24 00:01:05,721 --> 00:01:08,000 example for illustrating the scope of a trait. 25 00:01:08,001 --> 00:01:10,240 I will start by adding a library crate. 26 00:01:10,241 --> 00:01:15,360 [No Audio] 27 00:01:15,361 --> 00:01:17,440 I will declare a module of basic. 28 00:01:17,441 --> 00:01:20,480 [No Audio] 29 00:01:20,481 --> 00:01:24,600 This module will have a public personal_info trait, 30 00:01:24,601 --> 00:01:26,400 which will contain a function of 31 00:01:26,401 --> 00:01:29,720 how_old which will return the age as a u8. 32 00:01:29,721 --> 00:01:36,000 [No Audio] 33 00:01:36,001 --> 00:01:38,200 Next, I will define a public structure of 34 00:01:38,201 --> 00:01:41,160 Student containing a couple of fields of name and age. 35 00:01:41,161 --> 00:01:46,480 [No Audio] 36 00:01:46,481 --> 00:01:50,120 Next, we will implement the personal_info. 37 00:01:50,121 --> 00:01:53,880 [No Audio] 38 00:01:53,881 --> 00:01:55,400 Let us include the definition 39 00:01:55,401 --> 00:01:57,400 of how_old function now. 40 00:01:57,401 --> 00:02:01,840 [No Audio] 41 00:02:01,841 --> 00:02:04,800 Next, we will define some_fn, which will 42 00:02:04,801 --> 00:02:07,400 make use of the how_old function 43 00:02:07,401 --> 00:02:09,000 within the same module. 44 00:02:09,001 --> 00:02:11,320 [No Audio] 45 00:02:11,321 --> 00:02:13,800 I will define an instance with some values. 46 00:02:13,801 --> 00:02:17,480 [No Audio] 47 00:02:17,481 --> 00:02:19,280 Next, I will call the function 48 00:02:19,281 --> 00:02:21,960 of how_old on this instance. 49 00:02:21,961 --> 00:02:24,320 [No Audio] 50 00:02:24,321 --> 00:02:26,480 Now if I remove the pub keyword 51 00:02:26,481 --> 00:02:29,400 from the trait, the trait is still in scope, 52 00:02:29,401 --> 00:02:31,600 and therefore there won't be any issues. 53 00:02:32,000 --> 00:02:34,520 However, if I keep the trait private to the 54 00:02:34,521 --> 00:02:36,920 module, and use the same function outside the 55 00:02:36,921 --> 00:02:39,600 module, the compiler will not be happy. Let 56 00:02:39,601 --> 00:02:41,880 me copy the code of the function and paste it 57 00:02:41,881 --> 00:02:43,280 outside the module. 58 00:02:43,281 --> 00:02:46,200 [No Audio] 59 00:02:46,201 --> 00:02:48,000 I will first bring the relevant items 60 00:02:48,001 --> 00:02:49,720 from the module into scope of 61 00:02:49,721 --> 00:02:51,920 the function. This is because, they will not 62 00:02:51,921 --> 00:02:53,680 be in scope by default, because they are 63 00:02:53,681 --> 00:02:56,680 residing in a different module. You may note 64 00:02:56,681 --> 00:02:59,280 that there are errors indicating to us that 65 00:02:59,281 --> 00:03:01,680 the trait personal_info is private. This 66 00:03:01,681 --> 00:03:03,680 means that by default, the trait is only 67 00:03:03,681 --> 00:03:05,720 available to us within the module or sub 68 00:03:05,721 --> 00:03:07,840 modules of the main module in which it is 69 00:03:07,841 --> 00:03:11,200 defined. Let us go ahead and make the trait public. 70 00:03:11,201 --> 00:03:13,480 [No Audio] 71 00:03:13,481 --> 00:03:16,200 The compiler is now happy and has no issues. 72 00:03:17,000 --> 00:03:19,000 It is not always necessary and 73 00:03:19,001 --> 00:03:21,600 mandatory to have the trait definition and 74 00:03:21,601 --> 00:03:24,000 its implementation for a specific type to be 75 00:03:24,001 --> 00:03:26,520 always in the same module. The trait 76 00:03:26,521 --> 00:03:29,120 definition may be in one module, and its 77 00:03:29,160 --> 00:03:31,560 implementation may be in another module. 78 00:03:32,280 --> 00:03:35,080 We just need to make sure that module in which 79 00:03:35,081 --> 00:03:37,440 we intend to have implementation of a trait 80 00:03:37,441 --> 00:03:40,280 for a specific type must bring the trait into 81 00:03:40,281 --> 00:03:43,920 its scope. For instance, I will define another module. 82 00:03:43,921 --> 00:03:48,640 [No Audio] 83 00:03:48,641 --> 00:03:52,240 I will bring the personal_info trait into scope first. 84 00:03:52,241 --> 00:03:57,600 [No Audio] 85 00:03:57,601 --> 00:04:00,600 Next I will define another struct called Person. 86 00:04:00,601 --> 00:04:05,240 [No Audio] 87 00:04:05,241 --> 00:04:08,640 I will implement the personal_info for Person. 88 00:04:08,641 --> 00:04:12,880 [No Audio] 89 00:04:12,881 --> 00:04:16,399 Finally, I will add the definition of how_old function. 90 00:04:16,400 --> 00:04:20,880 [No Audio] 91 00:04:20,881 --> 00:04:23,400 This will work fine, as long as the 92 00:04:23,401 --> 00:04:25,800 personal_info is public. However, 93 00:04:25,801 --> 00:04:28,040 if we make the personal_info private, 94 00:04:28,041 --> 00:04:31,120 then it will not work. Let me make it private. 95 00:04:32,000 --> 00:04:34,480 The compiler is indicating to us some errors. 96 00:04:34,800 --> 00:04:36,840 The summary is that like structs, functions, 97 00:04:36,841 --> 00:04:39,840 and enums, we can also make the traits public 98 00:04:39,841 --> 00:04:41,880 or private for controlling its scope and 99 00:04:41,881 --> 00:04:45,200 visibility inside the code. To get around the 100 00:04:45,201 --> 00:04:47,040 error in this case, we can either make the 101 00:04:47,041 --> 00:04:49,480 trait public or move the module inside the 102 00:04:49,481 --> 00:04:52,520 basic module. Both the options are available 103 00:04:52,521 --> 00:04:55,280 and are dependent on your underlying design, 104 00:04:55,560 --> 00:04:57,720 and you have to decide it carefully for 105 00:04:57,721 --> 00:05:00,600 proper organization of your code. Let us make 106 00:05:00,601 --> 00:05:04,280 it public for now. Finally, the same rules 107 00:05:04,281 --> 00:05:06,760 will apply if we intend to use the trait of 108 00:05:06,761 --> 00:05:09,160 personal_info in the main program. 109 00:05:09,600 --> 00:05:11,920 This is quite obvious, so we will leave the 110 00:05:11,921 --> 00:05:14,400 details of that and we'll move to the next topic. 111 00:05:16,240 --> 00:05:18,560 The next topic is with regards to 112 00:05:18,561 --> 00:05:20,440 trait methods with the same name for the 113 00:05:20,441 --> 00:05:22,840 type. When we have a trait with a method 114 00:05:22,841 --> 00:05:26,040 which is implemented for a specific type, and 115 00:05:26,041 --> 00:05:28,440 the type itself also has an implementation 116 00:05:28,441 --> 00:05:30,800 for the same method, then the compiler 117 00:05:30,801 --> 00:05:32,480 defaults to calling the method that is 118 00:05:32,481 --> 00:05:34,520 directly implemented on the type itself. 119 00:05:35,520 --> 00:05:38,440 Let us see the details with an example. Consider a 120 00:05:38,441 --> 00:05:40,840 Pilot trait with a method of fly. 121 00:05:40,841 --> 00:05:44,000 [No Audio] 122 00:05:44,001 --> 00:05:46,760 Let us define another trait of Wizard also 123 00:05:46,761 --> 00:05:48,400 containing the fly method. 124 00:05:48,401 --> 00:05:50,960 [No Audio] 125 00:05:50,961 --> 00:05:52,960 Next, let us define a Human 126 00:05:52,961 --> 00:05:54,600 struct with no fields. 127 00:05:54,601 --> 00:05:57,320 [No Audio] 128 00:05:57,321 --> 00:06:00,040 Let us now implement the two traits for the Human. 129 00:06:00,360 --> 00:06:03,200 First, we will implement the Pilot trait for Human. 130 00:06:03,201 --> 00:06:05,200 [No Audio] 131 00:06:05,201 --> 00:06:07,720 Let us say the fly method definition now. 132 00:06:07,721 --> 00:06:13,440 [No Audio] 133 00:06:13,441 --> 00:06:15,800 Next, we will implement the Wizard for Human. 134 00:06:15,801 --> 00:06:17,880 [No Audio] 135 00:06:17,881 --> 00:06:19,840 Let us say the function of fly. 136 00:06:19,841 --> 00:06:24,400 [No Audio] 137 00:06:24,401 --> 00:06:26,720 Finally, we will directly implement the fly 138 00:06:26,721 --> 00:06:28,640 inside the implementation of Human. 139 00:06:28,641 --> 00:06:33,160 [No Audio] 140 00:06:33,161 --> 00:06:35,400 You may have noticed that, now we have three 141 00:06:35,401 --> 00:06:37,920 implementations of the same function of fly 142 00:06:37,921 --> 00:06:40,800 for Human in three different contexts of Pilot, 143 00:06:40,840 --> 00:06:43,320 Wizard, and a direct implementation inside the 144 00:06:43,321 --> 00:06:46,800 Human. As pointed out earlier, when the type 145 00:06:46,801 --> 00:06:49,400 itself implements a method, so by default, its 146 00:06:49,401 --> 00:06:52,600 own version will be invoked. In this case, we 147 00:06:52,601 --> 00:06:54,400 are expecting the fly within the Human 148 00:06:54,401 --> 00:06:57,360 implementation to be invoked. Let us see if 149 00:06:57,361 --> 00:06:59,480 this is the case. In the main, I will first 150 00:06:59,481 --> 00:07:01,680 create an instance of the Human. 151 00:07:01,681 --> 00:07:06,360 [No Audio] 152 00:07:06,361 --> 00:07:09,400 Next, I will call the fly on the Human. 153 00:07:11,280 --> 00:07:13,280 Let us execute to see which function 154 00:07:13,281 --> 00:07:14,800 will be invoked in this case. 155 00:07:14,801 --> 00:07:18,440 [No Audio] 156 00:07:18,441 --> 00:07:20,400 As expected, the function inside the 157 00:07:20,401 --> 00:07:22,600 implementation of the type itself has been 158 00:07:22,601 --> 00:07:24,800 invoked. To invoke the specific 159 00:07:24,801 --> 00:07:27,600 implementations for the type. We will not use 160 00:07:27,601 --> 00:07:29,920 the dot notation, but rather will use the full 161 00:07:29,960 --> 00:07:31,800 information of the function with proper 162 00:07:31,801 --> 00:07:34,040 inputs. For instance, to invoke the 163 00:07:34,041 --> 00:07:36,960 implementation provided by the pilot trait, we 164 00:07:36,961 --> 00:07:38,520 will use this syntax. 165 00:07:38,521 --> 00:07:41,280 [No Audio] 166 00:07:41,281 --> 00:07:42,680 In the same way, to invoke the 167 00:07:42,681 --> 00:07:44,320 implementation inside the Wizard 168 00:07:44,321 --> 00:07:46,800 trait, we will use this syntax. 169 00:07:46,801 --> 00:07:49,960 [No Audio] 170 00:07:49,961 --> 00:07:51,120 Let us now move to the 171 00:07:51,121 --> 00:07:53,280 next topic of super traits, but first 172 00:07:53,281 --> 00:07:54,720 I will comment out the code. 173 00:07:54,721 --> 00:08:00,280 [No Audio] 174 00:08:00,281 --> 00:08:03,400 Rust doesn't have inheritance, but you can 175 00:08:03,401 --> 00:08:05,680 define a trait as being a super trait of 176 00:08:05,681 --> 00:08:09,120 another trait. Super traits are a feature of 177 00:08:09,121 --> 00:08:11,920 Rust's trait system that allows one trait to 178 00:08:11,921 --> 00:08:14,560 inherit methods and associated types from 179 00:08:14,561 --> 00:08:17,640 another trait. When a trait inherits from 180 00:08:17,641 --> 00:08:20,000 another trait, it gains access to all the 181 00:08:20,001 --> 00:08:22,680 methods and associated types of the parent 182 00:08:22,681 --> 00:08:25,440 trait. This is similar to inheritance in 183 00:08:25,441 --> 00:08:27,400 object oriented programming in other 184 00:08:27,401 --> 00:08:30,240 languages, where a subclass can inherit 185 00:08:30,241 --> 00:08:33,000 methods and properties from a parent class. 186 00:08:33,600 --> 00:08:35,559 Let us see some examples to illustrate the 187 00:08:35,560 --> 00:08:39,000 key ideas. I will define a trait of person 188 00:08:39,001 --> 00:08:40,640 containing a function of name. 189 00:08:40,641 --> 00:08:45,800 [No Audio] 190 00:08:45,801 --> 00:08:47,920 Next, I will define another trait called 191 00:08:47,921 --> 00:08:50,400 Student with a Person being it's super trait. 192 00:08:50,401 --> 00:08:54,600 [No Audio] 193 00:08:54,601 --> 00:08:56,680 The colon followed by the trait after the 194 00:08:56,681 --> 00:08:58,600 name of the trait, is the syntax for 195 00:08:58,601 --> 00:09:01,440 mentioning a super trait for the trait. In 196 00:09:01,441 --> 00:09:03,600 this case the Person is a super trait for the 197 00:09:03,601 --> 00:09:06,600 Student trait. The key requirement for any 198 00:09:06,601 --> 00:09:09,360 type now that implements the Student trait 199 00:09:09,400 --> 00:09:11,880 is that, it also needs to have an 200 00:09:11,881 --> 00:09:14,640 implementation for the Person trait. This 201 00:09:14,641 --> 00:09:16,440 means that, any type which implements the 202 00:09:16,441 --> 00:09:19,360 Student trait must also implement the Person 203 00:09:19,361 --> 00:09:22,960 trait. Let us include a function of complete_info 204 00:09:22,961 --> 00:09:24,440 inside the Student trait with an 205 00:09:24,441 --> 00:09:27,040 input of self and an output of a tuple. 206 00:09:27,041 --> 00:09:32,840 [No Audio] 207 00:09:32,841 --> 00:09:35,120 Let us now see how we can implement the trait 208 00:09:35,121 --> 00:09:37,760 for a specific type. I will define a 209 00:09:37,761 --> 00:09:39,920 university_student struct. 210 00:09:39,921 --> 00:09:42,480 [No Audio] 211 00:09:42,481 --> 00:09:44,360 The structure will have three fields. 212 00:09:44,361 --> 00:09:47,480 [No Audio] 213 00:09:47,481 --> 00:09:50,920 Next we will implement the Student for university student. 214 00:09:50,921 --> 00:09:54,160 [No Audio] 215 00:09:54,161 --> 00:09:56,800 Let us include the function of complete_info. 216 00:09:56,801 --> 00:10:00,440 [No Audio] 217 00:10:00,441 --> 00:10:03,320 The function will return a tuple with the first value being the 218 00:10:03,321 --> 00:10:05,720 name, the second value being the age, and the 219 00:10:05,721 --> 00:10:08,560 third value being the university of the Student. 220 00:10:08,561 --> 00:10:15,560 [No Audio] 221 00:10:15,561 --> 00:10:17,720 You may note that we do not have the name 222 00:10:17,721 --> 00:10:20,200 method implemented for the Student for now. 223 00:10:20,201 --> 00:10:22,640 This method will be used from the parent 224 00:10:22,641 --> 00:10:25,120 trait implementation, so this means that we 225 00:10:25,121 --> 00:10:27,440 also need to implement the parent trait for 226 00:10:27,441 --> 00:10:29,800 the type of university_student. 227 00:10:29,801 --> 00:10:32,160 There is also an error that is being 228 00:10:32,161 --> 00:10:34,440 indicated by the compiler, let us see the 229 00:10:34,441 --> 00:10:39,280 details. It says the trait bound uni_student: Person 230 00:10:39,281 --> 00:10:42,000 is not satisfied, the trait person is not 231 00:10:42,001 --> 00:10:43,800 implemented for uni_student. 232 00:10:45,080 --> 00:10:47,200 The compiler is also indicating to 233 00:10:47,201 --> 00:10:49,800 use the Person trait which is not implemented 234 00:10:49,801 --> 00:10:53,320 for the type. Another way of thinking about 235 00:10:53,321 --> 00:10:55,440 the parent trait is that, when we declare a 236 00:10:55,441 --> 00:10:58,000 trait to be a parent trait, then in some 237 00:10:58,001 --> 00:11:00,240 sense, we are associating some extra 238 00:11:00,241 --> 00:11:02,960 properties with the type, which also needs to 239 00:11:02,961 --> 00:11:05,040 be satisfied for that particular type. 240 00:11:05,120 --> 00:11:07,800 In other words, the type must also have these 241 00:11:07,801 --> 00:11:10,960 additional properties, let us implement the parent trait now. 242 00:11:10,961 --> 00:11:18,000 [No Audio] 243 00:11:18,001 --> 00:11:20,400 Next, let us also include the method of name 244 00:11:20,401 --> 00:11:22,400 which will return the name of the Student. 245 00:11:22,401 --> 00:11:27,640 [No Audio] 246 00:11:27,641 --> 00:11:29,800 Now, the compiler is no more complaining as 247 00:11:29,801 --> 00:11:32,320 the requirements are being fulfilled, that is, 248 00:11:32,321 --> 00:11:34,360 any type which implements the child trait 249 00:11:34,600 --> 00:11:37,400 must also implement a parent trait or super 250 00:11:37,401 --> 00:11:40,480 trait. Let us use these implementations in 251 00:11:40,481 --> 00:11:42,720 the main now. I will create an instance of 252 00:11:42,721 --> 00:11:44,800 the university Student initialized from 253 00:11:44,801 --> 00:11:46,280 some suitable values. 254 00:11:46,281 --> 00:11:57,640 [No Audio] 255 00:11:57,641 --> 00:11:59,960 I will now call the complete_info 256 00:11:59,961 --> 00:12:02,400 function, which will enable us to use the 257 00:12:02,401 --> 00:12:04,240 parent track method of name. 258 00:12:04,241 --> 00:12:07,920 [No Audio] 259 00:12:07,921 --> 00:12:11,000 I can also directly call the parent trait methods, 260 00:12:11,001 --> 00:12:13,320 since they are also implemented for the type. 261 00:12:13,321 --> 00:12:16,800 [No Audio] 262 00:12:16,801 --> 00:12:18,920 Now, any type which is Student can access the 263 00:12:18,921 --> 00:12:21,560 super trait Person methods. To see this more 264 00:12:21,561 --> 00:12:24,200 clearly, I will define a function called info. 265 00:12:24,201 --> 00:12:28,000 [No Audio] 266 00:12:28,001 --> 00:12:30,600 This function we'll use a generic type s 267 00:12:30,640 --> 00:12:32,360 which will have the Student trait. 268 00:12:32,361 --> 00:12:37,000 [No Audio] 269 00:12:37,001 --> 00:12:40,000 The input to the function will be a reference to s. 270 00:12:40,001 --> 00:12:44,000 [No Audio] 271 00:12:44,001 --> 00:12:45,640 Inside the function, I will access the 272 00:12:45,641 --> 00:12:48,080 complete_info which is implemented for the 273 00:12:48,081 --> 00:12:49,880 Student inside the print statement. 274 00:12:49,881 --> 00:12:53,400 [No Audio] 275 00:12:53,401 --> 00:12:56,400 I will also access the name function which is not 276 00:12:56,401 --> 00:12:58,480 part of the Student trait, but it's part of 277 00:12:58,481 --> 00:12:59,800 the super trait Person. 278 00:12:59,801 --> 00:13:04,080 [No Audio] 279 00:13:04,081 --> 00:13:05,520 This means now, that the 280 00:13:05,521 --> 00:13:07,200 super trait methods are also 281 00:13:07,201 --> 00:13:09,760 accessible to us, although the generic is of type 282 00:13:09,761 --> 00:13:13,880 Student and not that of a Person. Let us call the info 283 00:13:13,881 --> 00:13:16,440 function in the main now with the reference to s. 284 00:13:16,441 --> 00:13:19,520 [No Audio] 285 00:13:19,521 --> 00:13:21,160 Let us cargo run this now. 286 00:13:21,161 --> 00:13:26,920 [No Audio] 287 00:13:26,921 --> 00:13:29,120 With regards to the super traits, there is a 288 00:13:29,121 --> 00:13:32,360 closely related concept of combo traits. 289 00:13:33,000 --> 00:13:35,600 Combo traits refers to the use of multiple 290 00:13:35,601 --> 00:13:38,400 traits and capacity of super traits. Let us 291 00:13:38,401 --> 00:13:41,000 extend the current example to explain this. 292 00:13:41,120 --> 00:13:43,560 Let me add one more trait called Programmer, 293 00:13:43,720 --> 00:13:46,400 which will have a single function of favorite language. 294 00:13:46,401 --> 00:13:50,120 [No Audio] 295 00:13:50,121 --> 00:13:52,120 Next, I will define another trait 296 00:13:52,121 --> 00:13:54,200 called computer science student, and we'll 297 00:13:54,201 --> 00:13:57,440 mention multiple traits as its super traits. 298 00:13:57,441 --> 00:14:03,280 [No Audio] 299 00:14:03,281 --> 00:14:05,280 The plus means that the trait computer 300 00:14:05,281 --> 00:14:07,600 science student will have both the Programmer 301 00:14:07,640 --> 00:14:11,000 and the Student as its super traits. This is 302 00:14:11,001 --> 00:14:13,800 also referred to as combo traits, which is 303 00:14:13,801 --> 00:14:16,200 used to mention multiple traits as super 304 00:14:16,201 --> 00:14:19,360 traits. Please note now that in this case, 305 00:14:19,361 --> 00:14:21,320 implementing the computer science student for 306 00:14:21,321 --> 00:14:23,400 a certain type will require us to implement 307 00:14:23,401 --> 00:14:25,280 both the super traits of Programmer and 308 00:14:25,281 --> 00:14:27,800 Student. Moreover, since Student has a super 309 00:14:27,801 --> 00:14:30,600 trait of person, so implementing type must 310 00:14:30,601 --> 00:14:33,600 also have the implementation for the Person trait. 311 00:14:33,601 --> 00:14:35,840 Let us now move to the topic of marker 312 00:14:35,841 --> 00:14:38,520 traits, but first I will comment out the code. 313 00:14:38,521 --> 00:14:42,960 [No Audio] 314 00:14:42,961 --> 00:14:45,680 A marker trait is a trait that doesn't require 315 00:14:45,681 --> 00:14:48,760 any methods to be implemented. Moreover, it 316 00:14:48,800 --> 00:14:51,840 also does not have any trait items. Instead, 317 00:14:51,841 --> 00:14:54,400 it serves as a way to add metadata or 318 00:14:54,401 --> 00:14:57,280 constraints to a type. Marker traits are 319 00:14:57,281 --> 00:14:59,640 useful in Rust, because they allow us to 320 00:14:59,641 --> 00:15:01,480 commute additional information 321 00:15:01,481 --> 00:15:03,600 about a type to the compiler without 322 00:15:03,601 --> 00:15:06,000 requiring any actual functionality to be 323 00:15:06,001 --> 00:15:09,080 implemented. This can be helpful in cases 324 00:15:09,081 --> 00:15:11,680 where we need to specify certain behaviors or 325 00:15:11,681 --> 00:15:14,160 properties of a type without actually 326 00:15:14,161 --> 00:15:16,960 providing any concrete implementations. 327 00:15:17,080 --> 00:15:20,360 Let us see an example of this. I will define a 328 00:15:20,361 --> 00:15:22,560 trait called Some_properties, 329 00:15:22,640 --> 00:15:25,200 which will have Clone, PartialEq, and 330 00:15:25,201 --> 00:15:27,440 Default as its super traits. 331 00:15:27,441 --> 00:15:30,800 [No Audio] 332 00:15:30,801 --> 00:15:33,400 The plus is used to mention the combo traits 333 00:15:33,401 --> 00:15:35,840 and the colon in the syntax for mentioning 334 00:15:35,841 --> 00:15:38,600 the super traits. This means now that 335 00:15:38,601 --> 00:15:40,680 all these traits are the super traits 336 00:15:40,681 --> 00:15:43,000 have the Some_properties traits. 337 00:15:43,560 --> 00:15:45,240 Now, as pointed out a few 338 00:15:45,241 --> 00:15:48,000 times earlier also, any type which has the 339 00:15:48,001 --> 00:15:50,400 Some_properties trait will also 340 00:15:50,401 --> 00:15:52,280 have the Clone, PartialEq, and the 341 00:15:52,281 --> 00:15:54,800 Default traits. This means now that by 342 00:15:54,801 --> 00:15:57,400 declaring a type to have Some_properties, 343 00:15:57,401 --> 00:15:59,080 we are putting a restriction on 344 00:15:59,081 --> 00:16:01,480 this type or marking the type that it must 345 00:16:01,481 --> 00:16:03,600 also have the Clone, PartialEq, and 346 00:16:03,601 --> 00:16:07,560 Default traits. Let us declare a Student struct next. 347 00:16:07,561 --> 00:16:12,160 [No Audio] 348 00:16:12,161 --> 00:16:14,200 The structure will have three fields. 349 00:16:14,201 --> 00:16:17,000 [No Audio] 350 00:16:17,001 --> 00:16:18,880 Since the Some_properties 351 00:16:18,881 --> 00:16:21,640 does not have anything to being implemented, 352 00:16:21,641 --> 00:16:24,840 so therefore it just serve as a marker. 353 00:16:24,841 --> 00:16:26,680 Next, we will implement the sum underscore 354 00:16:26,681 --> 00:16:28,000 properties for Student. 355 00:16:28,001 --> 00:16:31,880 [No Audio] 356 00:16:31,881 --> 00:16:33,720 You may note that the compiler is not happy, 357 00:16:33,721 --> 00:16:35,600 it says the trait bound Student 358 00:16:35,601 --> 00:16:38,400 call on Default is not satisfied. The 359 00:16:38,401 --> 00:16:40,920 trait Default is not implemented for Student, 360 00:16:40,921 --> 00:16:42,360 let us add the Default. 361 00:16:42,361 --> 00:16:45,360 [No Audio] 362 00:16:45,361 --> 00:16:47,400 You may note that it is still complaining, 363 00:16:47,760 --> 00:16:49,600 it will keep on complaining until 364 00:16:49,601 --> 00:16:51,240 and unless we derive all 365 00:16:51,241 --> 00:16:53,320 the required traits for the type. So let us 366 00:16:53,321 --> 00:16:55,360 look at all the required traits. 367 00:16:55,361 --> 00:17:00,040 [No Audio] 368 00:17:00,041 --> 00:17:03,440 The code is now compiling. In summary, the marker traits 369 00:17:03,441 --> 00:17:05,800 are useful for mentioning some constraints on 370 00:17:05,801 --> 00:17:08,319 a type. Let us now cover the last topic, 371 00:17:08,320 --> 00:17:10,640 which is the auto traits, but first, I will 372 00:17:10,641 --> 00:17:11,839 comment out the code. 373 00:17:11,840 --> 00:17:16,960 [No Audio] 374 00:17:16,961 --> 00:17:19,000 Auto traits are traits that get 375 00:17:19,001 --> 00:17:21,480 automatically implemented for a type, if all 376 00:17:21,481 --> 00:17:24,520 of its members also implement the trait. What 377 00:17:24,521 --> 00:17:26,599 member means depends on the type, for 378 00:17:26,600 --> 00:17:29,480 example, fields of a struct or variants of an 379 00:17:29,481 --> 00:17:32,200 enum. Let us see an example to understand 380 00:17:32,201 --> 00:17:34,800 auto traits. Consider a simple customer 381 00:17:34,801 --> 00:17:36,120 struct with two fields. 382 00:17:36,121 --> 00:17:40,320 [No Audio] 383 00:17:40,321 --> 00:17:41,600 Let us add the Default 384 00:17:41,601 --> 00:17:43,480 trait to this type by deriving it. 385 00:17:43,481 --> 00:17:47,200 [No Audio] 386 00:17:47,201 --> 00:17:49,520 There were no issues, because the members have 387 00:17:49,521 --> 00:17:51,960 the type, which in this case are the fields of 388 00:17:51,961 --> 00:17:54,280 the struct also have the implementation for 389 00:17:54,281 --> 00:17:57,040 the Default. In fact, all the primitive types 390 00:17:57,041 --> 00:17:59,880 implements the Default trait. This means that 391 00:17:59,881 --> 00:18:02,080 the Default trait is an auto trait for the 392 00:18:02,081 --> 00:18:04,760 customer. Since all of its types also 393 00:18:04,761 --> 00:18:07,040 implements this trait, however, if we add 394 00:18:07,041 --> 00:18:09,800 another type to it, which which does not have 395 00:18:09,801 --> 00:18:12,240 the default implementation, then the compiler 396 00:18:12,241 --> 00:18:14,720 will not be happy and it will not consider it 397 00:18:14,721 --> 00:18:17,520 to be an auto trait. Let me add another field 398 00:18:17,521 --> 00:18:19,880 of relationship to the customer which will be 399 00:18:19,881 --> 00:18:21,400 an enum with type visit. 400 00:18:21,401 --> 00:18:25,000 [No Audio] 401 00:18:25,001 --> 00:18:26,680 Let us define the enum now. 402 00:18:26,681 --> 00:18:30,360 [No Audio] 403 00:18:30,361 --> 00:18:32,480 In order to make the Default as an 404 00:18:32,481 --> 00:18:34,480 auto trait, we will need to implement the 405 00:18:34,481 --> 00:18:38,400 Default for the Visit type also, so let us add this. 406 00:18:38,401 --> 00:18:42,520 [No Audio] 407 00:18:42,521 --> 00:18:44,400 The Default trait contains a single 408 00:18:44,401 --> 00:18:46,800 function of Default, so let us add that. 409 00:18:46,801 --> 00:18:50,280 [No Audio] 410 00:18:50,281 --> 00:18:53,080 The function will return a variant of new as a 411 00:18:53,081 --> 00:18:55,520 Default value. Now you may note that the 412 00:18:55,521 --> 00:18:57,920 compiler has no issues, we can now use this 413 00:18:57,921 --> 00:18:59,840 function to initialize an instance 414 00:18:59,841 --> 00:19:01,200 of the struct in the main. 415 00:19:01,201 --> 00:19:06,280 [No Audio] 416 00:19:06,281 --> 00:19:08,200 With this we end this tutorial, I hope you 417 00:19:08,201 --> 00:19:10,120 would have enjoyed this. See you again and 418 00:19:10,121 --> 00:19:12,680 until next tutorial, enjoy Rust programming