1 00:00:00,000 --> 00:00:07,960 [No Audio] 2 00:00:08,000 --> 00:00:10,360 In this tutorial, we will be talking about 3 00:00:10,361 --> 00:00:13,200 trait items. Some of these items are already 4 00:00:13,201 --> 00:00:14,800 somewhat covered in some of the previous 5 00:00:14,801 --> 00:00:16,520 tutorials, so we will go through them 6 00:00:16,521 --> 00:00:19,720 quickly. The trait items are any items that 7 00:00:19,721 --> 00:00:22,240 are part of a trait declaration. This means 8 00:00:22,241 --> 00:00:24,800 that all the functions, associated types or 9 00:00:24,801 --> 00:00:27,560 generics that are declared as part of the trait 10 00:00:27,561 --> 00:00:30,600 declaration are trait items. Within the 11 00:00:30,601 --> 00:00:33,520 context of trait items, the first concept is 12 00:00:33,521 --> 00:00:35,640 that of the Self which generally confuses 13 00:00:35,641 --> 00:00:38,640 beginner level programmers. Let us develop a 14 00:00:38,641 --> 00:00:41,280 good understanding of what exactly do we mean 15 00:00:41,281 --> 00:00:43,200 by Self, I will define a simple trait 16 00:00:43,201 --> 00:00:44,840 containing a couple of functions. 17 00:00:44,841 --> 00:00:50,960 [No Audio] 18 00:00:50,961 --> 00:00:53,640 The first function returns a simple i32 19 00:00:53,641 --> 00:00:56,000 value, and the second function returns the 20 00:00:56,001 --> 00:00:58,480 implementation type which is indicated by the 21 00:00:58,481 --> 00:01:01,360 Self keyword. Within this context, it means the 22 00:01:01,361 --> 00:01:03,400 type for the simple trait which is being 23 00:01:03,401 --> 00:01:07,640 implemented. Let us now define a couple of unit structs. 24 00:01:07,641 --> 00:01:10,800 [No Audio] 25 00:01:10,801 --> 00:01:12,800 A unit struct is a special 26 00:01:12,801 --> 00:01:15,680 struct in Rust programming language with no fields. 27 00:01:15,681 --> 00:01:19,120 Next, let us define the simple trait for the SomeType. 28 00:01:19,121 --> 00:01:22,760 [No Audio] 29 00:01:22,761 --> 00:01:24,720 The fn_2 will return an 30 00:01:24,721 --> 00:01:26,400 instance of the Self, which 31 00:01:26,440 --> 00:01:28,920 refers to the implementing type, that is the 32 00:01:28,921 --> 00:01:32,240 SomeType itself within this implementation block. 33 00:01:32,241 --> 00:01:36,400 [No Audio] 34 00:01:36,401 --> 00:01:38,400 This means that, the Self means the 35 00:01:38,401 --> 00:01:41,280 type for which we are implementing the trait 36 00:01:41,281 --> 00:01:44,400 and is context dependent. Let us see it more 37 00:01:44,401 --> 00:01:46,360 clearly by implementing the trait for the 38 00:01:46,361 --> 00:01:49,000 other type. For the fn_1, we will 39 00:01:49,001 --> 00:01:51,240 again return some arbitrary value. 40 00:01:51,241 --> 00:01:55,240 [No Audio] 41 00:01:55,241 --> 00:01:58,280 For the second function, we will return other type. 42 00:01:58,281 --> 00:02:01,000 [No Audio] 43 00:02:01,001 --> 00:02:03,600 As you may have spotted, the meaning of Self 44 00:02:03,601 --> 00:02:06,280 in this context is now the other type, which 45 00:02:06,281 --> 00:02:08,199 is the type for which we are implementing the 46 00:02:08,200 --> 00:02:10,320 trait. Now, let us move to the second 47 00:02:10,321 --> 00:02:12,240 topic, which is with regards to the trait 48 00:02:12,280 --> 00:02:15,320 items of functions and methods. First, I will 49 00:02:15,321 --> 00:02:16,760 comment out the previous code. 50 00:02:16,761 --> 00:02:21,000 [No Audio] 51 00:02:21,001 --> 00:02:22,320 We will start by highlighting 52 00:02:22,321 --> 00:02:24,600 the key difference between functions and methods 53 00:02:24,601 --> 00:02:26,920 within the context of traits. 54 00:02:26,921 --> 00:02:29,160 A trait bound function is any 55 00:02:29,161 --> 00:02:32,040 function, whose first parameter does not use 56 00:02:32,041 --> 00:02:34,800 the Self keyword. A trait_method is any 57 00:02:34,801 --> 00:02:37,320 function whose first parameter uses the Self. 58 00:02:37,480 --> 00:02:39,600 Let us go through some examples to clearly 59 00:02:39,601 --> 00:02:42,320 understand the difference, I will define a 60 00:02:42,321 --> 00:02:43,680 simple trait of Default. 61 00:02:45,400 --> 00:02:48,800 I will add the default function which will return the Self. 62 00:02:48,801 --> 00:02:51,560 [No Audio] 63 00:02:51,561 --> 00:02:54,200 You may note that this is a function, since the 64 00:02:54,201 --> 00:02:57,200 first parameter is not that of Self. Let us 65 00:02:57,201 --> 00:02:59,400 implement this for an i32 value. 66 00:02:59,401 --> 00:03:05,000 [No Audio] 67 00:03:05,001 --> 00:03:07,440 The function will return a Default value of 68 00:03:07,441 --> 00:03:11,200 zero in this case. Let us use the 69 00:03:11,201 --> 00:03:14,760 implementation now in the main. I will call the function. 70 00:03:14,761 --> 00:03:18,240 [No Audio] 71 00:03:18,241 --> 00:03:19,880 The Rust compiler will complain 72 00:03:19,881 --> 00:03:22,520 if we do not provide the type, since there is 73 00:03:22,521 --> 00:03:25,240 no way to tell Rust that I am going to call 74 00:03:25,241 --> 00:03:27,920 this method for an i32 type, let us provide 75 00:03:27,921 --> 00:03:30,480 the type now. The function with no Self 76 00:03:30,481 --> 00:03:33,200 argument cannot be called like methods, for 77 00:03:33,201 --> 00:03:36,440 instance, I will define an i32 variable. 78 00:03:38,120 --> 00:03:40,240 Now, let us use the dot notation to 79 00:03:40,241 --> 00:03:44,600 access the function. As expected, the compiler 80 00:03:44,601 --> 00:03:46,840 is not happy. Let us inspect the error, 81 00:03:46,841 --> 00:03:50,880 it says, to be used as methods function and must 82 00:03:50,881 --> 00:03:53,600 have a self parameter. Now, let us look at 83 00:03:53,601 --> 00:03:57,240 some examples of trait_methods, I will add another trait. 84 00:03:57,241 --> 00:04:00,520 [No Audio] 85 00:04:00,521 --> 00:04:02,800 As pointed out earlier, a trait_method 86 00:04:02,801 --> 00:04:05,000 is any function whose first parameter 87 00:04:05,001 --> 00:04:08,160 uses the Self. The Self can appear as an own 88 00:04:08,161 --> 00:04:10,760 type, a reference to Self, or a mutable 89 00:04:10,761 --> 00:04:14,080 reference to Self. Let me add some functions to explain this. 90 00:04:14,081 --> 00:04:18,320 [No Audio] 91 00:04:18,321 --> 00:04:20,079 The first function is using 92 00:04:20,080 --> 00:04:23,000 an owned Self type, the second one is using a 93 00:04:23,001 --> 00:04:25,600 reference to Self, and the third is using a 94 00:04:25,601 --> 00:04:28,160 mutable reference to Self. The first function 95 00:04:28,161 --> 00:04:31,680 can be desugared into Self with a type of Self. 96 00:04:31,681 --> 00:04:34,960 [No Audio] 97 00:04:34,961 --> 00:04:37,000 Similarly, the second function can be 98 00:04:37,001 --> 00:04:40,640 desugared into Self with a type of reference to Self. 99 00:04:43,560 --> 00:04:45,960 The third one is similarly desugared 100 00:04:45,961 --> 00:04:48,520 into Self with a type of mutable reference to 101 00:04:48,521 --> 00:04:51,560 Self, and similarly, this small self refers to 102 00:04:51,561 --> 00:04:53,560 instance for which the function is being 103 00:04:53,561 --> 00:04:56,560 called when the Self with a capital refers to 104 00:04:56,561 --> 00:04:59,400 the type itself which can be owned reference 105 00:04:59,401 --> 00:05:02,600 or unmutable reference. We have used 106 00:05:02,601 --> 00:05:04,720 both the methods and functions in the 107 00:05:04,760 --> 00:05:06,560 BlockChain implementation section of the 108 00:05:06,561 --> 00:05:09,440 course. Let us see some examples of that in 109 00:05:09,441 --> 00:05:12,040 the code. I will comment out this code first. 110 00:05:12,041 --> 00:05:16,640 [No Audio] 111 00:05:16,641 --> 00:05:18,080 Next I will paste the code 112 00:05:18,081 --> 00:05:20,120 of the BlockChain implementation. 113 00:05:20,121 --> 00:05:23,760 [No Audio] 114 00:05:23,761 --> 00:05:25,080 In the BlockChain implementation, 115 00:05:25,081 --> 00:05:26,600 you may have spotted that the 116 00:05:26,601 --> 00:05:29,560 new is a function and not a method, however, 117 00:05:29,561 --> 00:05:31,880 the starting block is a method. Similarly 118 00:05:31,881 --> 00:05:34,400 try_add_block is also a 119 00:05:34,401 --> 00:05:38,120 method. In the same way, is_block_valid 120 00:05:38,121 --> 00:05:40,800 is also a method, the remaining functions in the same 121 00:05:40,801 --> 00:05:43,160 implementation blocks are also methods. 122 00:05:43,161 --> 00:05:45,800 However, in the block implementation, the new 123 00:05:45,801 --> 00:05:48,240 and mine, are both functions and not 124 00:05:48,241 --> 00:05:51,240 methods. Now, let us move to the most 125 00:05:51,241 --> 00:05:53,400 important and key concept, that is generic 126 00:05:53,401 --> 00:05:55,640 parameters and associated types and their 127 00:05:55,641 --> 00:05:57,960 relationship within the context of traits. 128 00:05:58,120 --> 00:06:00,880 I will comment out the code first and we'll start fresh. 129 00:06:00,881 --> 00:06:05,120 [No Audio] 130 00:06:05,121 --> 00:06:06,600 Both generic types and 131 00:06:06,601 --> 00:06:09,080 associated types defer the decision to the 132 00:06:09,081 --> 00:06:11,480 implementer on which concrete types should be 133 00:06:11,481 --> 00:06:14,040 used in the trait functions and methods. 134 00:06:14,041 --> 00:06:16,840 In these examples, we seek to explain when to use 135 00:06:16,841 --> 00:06:19,440 one over the other within the trait. The 136 00:06:19,441 --> 00:06:22,520 general rule of thumb is, use associated types 137 00:06:22,560 --> 00:06:25,000 when there should be only a single 138 00:06:25,001 --> 00:06:27,560 implementation of the trait per type and use 139 00:06:27,561 --> 00:06:30,120 generic types when there can be many possible 140 00:06:30,121 --> 00:06:33,400 implementations of the trait per type. Now, 141 00:06:33,401 --> 00:06:35,120 let's see an example to explain this in some 142 00:06:35,121 --> 00:06:38,200 detail. Let us define the add trait 143 00:06:38,201 --> 00:06:39,880 with some associated types. 144 00:06:39,881 --> 00:06:45,400 [No Audio] 145 00:06:45,401 --> 00:06:48,000 The trait will also contain an add function 146 00:06:48,001 --> 00:06:51,000 with the inputs of Self, and Rhs or right hand 147 00:06:51,001 --> 00:06:53,920 side, and the output type will be Self::Output. 148 00:06:53,921 --> 00:07:00,400 [No Audio] 149 00:07:00,401 --> 00:07:02,600 This is a general implementation of the trait 150 00:07:02,601 --> 00:07:05,960 add, which will let us add some sort of two 151 00:07:05,961 --> 00:07:08,480 things where one will be called the left hand 152 00:07:08,481 --> 00:07:10,800 side, and the other one will be called a right 153 00:07:10,801 --> 00:07:13,600 hand side. The Self for the associated type 154 00:07:13,601 --> 00:07:15,640 means that, these associated types will be 155 00:07:15,641 --> 00:07:17,760 defined based on the type for which the trait 156 00:07:17,761 --> 00:07:21,000 is being implemented, let us define a point struct. 157 00:07:21,001 --> 00:07:25,160 [No Audio] 158 00:07:25,161 --> 00:07:27,160 This structure will contain the x and 159 00:07:27,161 --> 00:07:28,960 y coordinates as fields. 160 00:07:28,961 --> 00:07:31,800 [No Audio] 161 00:07:31,801 --> 00:07:35,000 We will now implement the add trait for the point type. 162 00:07:35,001 --> 00:07:38,520 [No Audio] 163 00:07:38,521 --> 00:07:41,040 First, we will set the type of the right hand 164 00:07:41,041 --> 00:07:44,440 side or Rhs to that of a point. The output 165 00:07:44,441 --> 00:07:47,480 will also be a point, so let us set its type also. 166 00:07:47,481 --> 00:07:49,720 [No Audio] 167 00:07:49,721 --> 00:07:52,200 Finally, we will add a function with 168 00:07:52,201 --> 00:07:53,880 suitable inputs and outputs. 169 00:07:53,881 --> 00:07:57,600 [No Audio] 170 00:07:57,601 --> 00:07:58,960 We will return a point 171 00:07:58,961 --> 00:08:01,000 with the x axis value of Self 172 00:08:01,001 --> 00:08:03,600 being added to that of the right hand side x 173 00:08:03,601 --> 00:08:06,040 axis value, and the y axis value of Self 174 00:08:06,041 --> 00:08:08,600 being added to that of the right hand side of 175 00:08:08,601 --> 00:08:14,280 y axis value. We can also use the Rhs to be, 176 00:08:14,281 --> 00:08:17,600 to be of type point since Self::Rhs 177 00:08:17,601 --> 00:08:19,800 has a type of point in this case. 178 00:08:21,440 --> 00:08:23,680 In the same way, we can also use point as the 179 00:08:23,681 --> 00:08:26,280 return type, since Self::Output 180 00:08:26,281 --> 00:08:28,720 means a type of point in this case. 181 00:08:28,721 --> 00:08:31,480 [No Audio] 182 00:08:31,481 --> 00:08:33,559 Let us now use this in the main, 183 00:08:33,640 --> 00:08:35,400 I will create a couple of points. 184 00:08:35,401 --> 00:08:40,679 [No Audio] 185 00:08:40,680 --> 00:08:42,679 Next, I will call the add function 186 00:08:42,680 --> 00:08:45,960 [No Audio] 187 00:08:45,961 --> 00:08:48,400 That is now confirmed that the x axis value 188 00:08:48,401 --> 00:08:50,640 and the y axis values are equal to 3. 189 00:08:50,641 --> 00:08:55,800 [No Audio] 190 00:08:55,801 --> 00:08:57,080 Let us cargo run this now. 191 00:08:57,081 --> 00:09:02,160 [No Audio] 192 00:09:02,161 --> 00:09:04,600 This program is fine. However, let's say we 193 00:09:04,601 --> 00:09:07,120 want it to add the ability to add i32 194 00:09:07,121 --> 00:09:09,600 values two point, where i32 would 195 00:09:09,601 --> 00:09:12,000 be added to both the x and y members. 196 00:09:12,440 --> 00:09:14,920 Let us go ahead and create another implementation 197 00:09:14,921 --> 00:09:19,000 for the Add for Point, where Rhs will be an i32 value. 198 00:09:19,001 --> 00:09:24,000 [No Audio] 199 00:09:24,001 --> 00:09:26,320 We will set the type of RHS to date of an 200 00:09:26,321 --> 00:09:29,200 i32 value and the output will be a point. 201 00:09:29,201 --> 00:09:33,760 [No Audio] 202 00:09:33,761 --> 00:09:36,520 The right hand side or Rhs will be added to 203 00:09:36,521 --> 00:09:40,080 the x axis value, and y axis value inside the Add function. 204 00:09:40,081 --> 00:09:48,160 [No Audio] 205 00:09:48,161 --> 00:09:50,160 You may note that the compiler is not happy, 206 00:09:50,320 --> 00:09:52,840 it says conflicting implementation of trait 207 00:09:52,841 --> 00:09:56,160 add for type point. Since the add trait is 208 00:09:56,161 --> 00:09:59,160 not parameterised by any generic type, so we 209 00:09:59,161 --> 00:10:01,720 can only implement it once per type, which 210 00:10:01,721 --> 00:10:04,720 means, we can only pick the types for both Rhs 211 00:10:04,721 --> 00:10:08,040 and output once. To allow editing both points 212 00:10:08,041 --> 00:10:11,040 in i32 values to point, we have to 213 00:10:11,041 --> 00:10:14,080 refactor Rhs from an associated type to a 214 00:10:14,081 --> 00:10:16,440 generic type, which would allow us to 215 00:10:16,441 --> 00:10:18,840 implement a trait multiple times for point 216 00:10:19,000 --> 00:10:21,840 with different type arguments for Rhs. 217 00:10:22,080 --> 00:10:25,000 So, let us change the Rhs from an associated type 218 00:10:25,001 --> 00:10:27,120 to that of a generic type. 219 00:10:28,400 --> 00:10:30,800 First, we will change the definition of the trait by 220 00:10:30,801 --> 00:10:33,160 including a generic parameter of RHS. 221 00:10:33,161 --> 00:10:37,000 [No Audio] 222 00:10:37,001 --> 00:10:40,000 Next, we will comment out the Rhs type, since it is 223 00:10:40,001 --> 00:10:43,800 now being treated as generic. Next, we will 224 00:10:43,801 --> 00:10:46,480 remove the Self from the Rhs since it is now 225 00:10:46,481 --> 00:10:48,840 being treated as generic and not tied with 226 00:10:48,841 --> 00:10:50,960 the type itself for which we are implementing 227 00:10:50,961 --> 00:10:54,240 the trait anymore. Next, in the first 228 00:10:54,241 --> 00:10:56,360 implementation of the add, we will set the 229 00:10:56,361 --> 00:10:58,360 generic to that of a point, since this 230 00:10:58,361 --> 00:11:01,160 implementation is for the type point, where 231 00:11:01,161 --> 00:11:02,880 the generic should be treated as point. 232 00:11:02,881 --> 00:11:06,400 [No Audio] 233 00:11:06,401 --> 00:11:09,120 We will also remove the type Rhs equals to 234 00:11:09,121 --> 00:11:11,280 Point since that trait is no more using the 235 00:11:11,281 --> 00:11:14,800 Rhs associated type. In the same way, in the 236 00:11:14,801 --> 00:11:17,600 second implementation of the add, we will set 237 00:11:17,601 --> 00:11:20,200 the generic type to that of an i32 to let 238 00:11:20,201 --> 00:11:22,120 the compiler know that in this 239 00:11:22,121 --> 00:11:24,840 implementation, a generic of i32 should 240 00:11:24,841 --> 00:11:27,760 be used. Again we will remove the associated 241 00:11:27,761 --> 00:11:31,080 type, as it is no more required. You may have 242 00:11:31,081 --> 00:11:33,200 noted that, the generic allows us to have 243 00:11:33,201 --> 00:11:35,440 multiple implementation of the same trait for 244 00:11:35,441 --> 00:11:38,040 a single type, which is the type of point in 245 00:11:38,041 --> 00:11:41,280 this case. With associated type, it was not 246 00:11:41,281 --> 00:11:43,560 possible. In general, we will use the 247 00:11:43,561 --> 00:11:46,000 associated types when there is only a single 248 00:11:46,001 --> 00:11:47,960 implementation of the trait per type. 249 00:11:48,280 --> 00:11:50,000 However, if there are multiple 250 00:11:50,001 --> 00:11:51,840 implementations of the same types for a 251 00:11:51,841 --> 00:11:55,200 trait, then we will use the generics. Let us 252 00:11:55,201 --> 00:11:57,400 now use the implementation in the main, I will 253 00:11:57,401 --> 00:11:59,080 define a point first. 254 00:11:59,081 --> 00:12:02,880 [No Audio] 255 00:12:02,881 --> 00:12:04,040 Next, I will add an 256 00:12:04,041 --> 00:12:06,000 integer value to the point by calling the 257 00:12:06,001 --> 00:12:07,800 add function which is defined in the new 258 00:12:07,801 --> 00:12:11,360 implementation. Finally, let us use the 259 00:12:11,361 --> 00:12:14,560 assert to check if the value is updated correctly or not. 260 00:12:14,561 --> 00:12:19,160 [No Audio] 261 00:12:19,161 --> 00:12:20,400 Let us cargo run this now. 262 00:12:20,401 --> 00:12:24,320 [No Audio] 263 00:12:24,321 --> 00:12:26,440 Everything is fine up till now. Let us 264 00:12:26,441 --> 00:12:28,400 further extend the implementation by 265 00:12:28,401 --> 00:12:31,240 considering another case. Let's say we want 266 00:12:31,241 --> 00:12:33,960 to add a new type called line which contains 267 00:12:33,961 --> 00:12:36,680 two points. And now, there are there are some 268 00:12:36,681 --> 00:12:39,440 contexts within our program where adding two 269 00:12:39,441 --> 00:12:42,080 points should produce a line instead of a 270 00:12:42,081 --> 00:12:44,200 point. This means that the output is not 271 00:12:44,201 --> 00:12:47,040 necessarily, is not necessarily a point 272 00:12:47,041 --> 00:12:50,200 anymore, but can also be aligned. This is not 273 00:12:50,201 --> 00:12:52,240 possible, given the current design of the a 274 00:12:52,241 --> 00:12:55,160 trait where output is an associated type, but 275 00:12:55,161 --> 00:12:57,200 we can satisfy these new requirements by 276 00:12:57,201 --> 00:12:59,640 refactoring output from an associated type 277 00:12:59,641 --> 00:13:02,720 into generic type. Let us see how we can do this. 278 00:13:04,200 --> 00:13:06,560 Since the output can now be different 279 00:13:06,561 --> 00:13:08,200 in the different implementations, so 280 00:13:08,201 --> 00:13:10,320 therefore, we will consider it a generic 281 00:13:10,321 --> 00:13:12,880 type. So, let us change the definition of the trait. 282 00:13:12,881 --> 00:13:16,280 [No Audio] 283 00:13:16,281 --> 00:13:18,080 We will delete it as associated 284 00:13:18,081 --> 00:13:19,600 type from the trait definition. 285 00:13:19,601 --> 00:13:23,040 [No Audio] 286 00:13:23,041 --> 00:13:24,520 Finally, we will also remove 287 00:13:24,521 --> 00:13:25,800 the cell from the output. 288 00:13:27,080 --> 00:13:29,800 In the implementation now, we will use two generics 289 00:13:29,801 --> 00:13:32,240 instead of one. In the first implementation, 290 00:13:32,241 --> 00:13:34,720 both the Rhs and the output are points. 291 00:13:34,721 --> 00:13:39,040 [No Audio] 292 00:13:39,041 --> 00:13:41,600 We do not need the associated type of 293 00:13:41,601 --> 00:13:43,640 output in the trait implementation. 294 00:13:45,400 --> 00:13:47,720 In the second implementation, the Rhs 295 00:13:47,721 --> 00:13:49,840 is i32 and the output is a point. 296 00:13:49,841 --> 00:13:54,240 [No Audio] 297 00:13:54,241 --> 00:13:55,600 We will also remove the 298 00:13:55,601 --> 00:13:57,280 associated type of output. 299 00:13:58,760 --> 00:14:00,680 Now, to take care of the new requirements, 300 00:14:00,681 --> 00:14:02,400 we will first add a line struct 301 00:14:02,401 --> 00:14:04,280 with two fields of start and 302 00:14:04,281 --> 00:14:06,440 end, both of which will be of type Point. 303 00:14:06,441 --> 00:14:12,440 [No Audio] 304 00:14:12,441 --> 00:14:14,720 Next, we will add another implementation for 305 00:14:14,721 --> 00:14:17,400 adding a point to another point, the Rhs in 306 00:14:17,401 --> 00:14:20,080 this case will be a Point and the output will be a line. 307 00:14:20,081 --> 00:14:26,160 [No Audio] 308 00:14:26,161 --> 00:14:29,280 We will next add the definition for the add function. 309 00:14:29,281 --> 00:14:32,000 [No Audio] 310 00:14:32,001 --> 00:14:33,600 The input will be Self and 311 00:14:33,601 --> 00:14:36,240 the rhs and the output will be a line. 312 00:14:36,241 --> 00:14:39,080 [No Audio] 313 00:14:39,081 --> 00:14:41,840 We will return a Line with the start being equal 314 00:14:41,841 --> 00:14:44,560 to the point of Self, and the end being equal 315 00:14:44,561 --> 00:14:46,960 to the point and indicated by the right hand 316 00:14:46,961 --> 00:14:50,040 side. Let us now use it in the main. 317 00:14:50,640 --> 00:14:52,680 I will declare a couple of points. 318 00:14:52,681 --> 00:14:55,920 [No Audio] 319 00:14:55,921 --> 00:14:58,040 Next, I will call the add function. 320 00:14:58,041 --> 00:15:03,200 [No Audio] 321 00:15:03,201 --> 00:15:05,480 Please note that in this case, when I pass the 322 00:15:05,481 --> 00:15:07,720 parameter of p2, which is a point to the 323 00:15:07,721 --> 00:15:10,120 function, so both the implementation number 324 00:15:10,121 --> 00:15:12,440 one and implementation number three matches, 325 00:15:12,480 --> 00:15:15,120 where the right hand side is a point. This is 326 00:15:15,121 --> 00:15:17,320 because, in both the implementations, the 327 00:15:17,321 --> 00:15:20,000 function accepts a Self and a Point, so 328 00:15:20,001 --> 00:15:22,280 therefore, the compiler is confused. We need 329 00:15:22,281 --> 00:15:24,280 to somehow tell the compiler that I need to 330 00:15:24,281 --> 00:15:26,800 invoke the implementation number three, where 331 00:15:26,801 --> 00:15:29,520 I should get back a Line and not a Point. 332 00:15:30,240 --> 00:15:33,040 This tells the compiler now, that the user of 333 00:15:33,041 --> 00:15:35,640 the implementation wants to invoke the 334 00:15:35,641 --> 00:15:38,400 implementation, where the input is a point, and 335 00:15:38,401 --> 00:15:41,240 the output he is expecting is that of a line. 336 00:15:41,880 --> 00:15:44,800 In the same way, we will also need to mention 337 00:15:44,801 --> 00:15:46,880 the output type in the first call to the 338 00:15:46,881 --> 00:15:49,520 add function to help the compiler identify 339 00:15:49,521 --> 00:15:51,720 the correct implementation that needs to be 340 00:15:51,721 --> 00:15:54,080 invoked. Finally, I will add some assertion 341 00:15:54,081 --> 00:15:56,000 to make sure that our code is correct. 342 00:15:56,001 --> 00:16:00,480 [No Audio] 343 00:16:00,481 --> 00:16:02,240 Let us cargo run this now. 344 00:16:02,241 --> 00:16:05,160 [No Audio] 345 00:16:05,161 --> 00:16:06,320 With this, we end this 346 00:16:06,321 --> 00:16:08,600 tutorial. The key point to note is that, we 347 00:16:08,601 --> 00:16:10,520 need to use the associated types 348 00:16:10,521 --> 00:16:13,280 when there should only be a single 349 00:16:13,281 --> 00:16:15,240 implementation of the trait per type. 350 00:16:15,241 --> 00:16:17,480 However, we will prefer to use the generic 351 00:16:17,481 --> 00:16:19,720 types, when there can be many possible 352 00:16:19,721 --> 00:16:22,600 implementations of the trait per type. See you again 353 00:16:22,601 --> 00:16:25,560 and until next tutorial, happy Rust programming.