1 00:00:06,000 --> 00:00:12,870 As you might have noticed, closures do not require us to annotate the types being used because closures 2 00:00:12,870 --> 00:00:15,570 are typically short and have a narrow context. 3 00:00:15,570 --> 00:00:22,200 The compiler is able to reliably infer the types of parameters being used as well as the return type, 4 00:00:22,500 --> 00:00:25,500 but we can still annotate the types if we wanted to. 5 00:00:25,770 --> 00:00:33,330 So to see an example of this, we'll create an add closure which is going to accept a parameter of type 6 00:00:33,330 --> 00:00:42,780 IE 32 and then it's going to return an I 32 and then we're just going to have it add one to the value 7 00:00:42,780 --> 00:00:43,410 we get. 8 00:00:44,910 --> 00:00:48,210 But as we already saw, we also don't have to have annotation. 9 00:00:48,210 --> 00:00:55,620 So I'll create the same closure and I'll just call it add v two for version two and we'll accept in 10 00:00:55,620 --> 00:01:00,630 our X argument and then we'll just add one to it. 11 00:01:01,710 --> 00:01:06,450 But as you can see, this X is underlined and it says a type annotation is needed. 12 00:01:07,520 --> 00:01:11,360 Well, in order for the compiler to infer what. 13 00:01:13,530 --> 00:01:16,440 It will require we actually have to use it. 14 00:01:16,440 --> 00:01:23,400 So in this case, as soon as we call it and then pass into one, it's able to infer, hey, we are using 15 00:01:23,580 --> 00:01:25,260 type I 32. 16 00:01:27,370 --> 00:01:35,200 But once we let the compiler infer the type, then that is the type that must continue to be used. 17 00:01:35,200 --> 00:01:42,310 Otherwise it will create an error and we can very easily see an example of this and we'll create a closure 18 00:01:42,310 --> 00:01:46,600 that accepts one argument and then it's just going to immediately return it. 19 00:01:48,950 --> 00:01:50,330 So we'll say. 20 00:01:52,480 --> 00:01:55,450 Let's string equals example. 21 00:01:55,450 --> 00:02:02,200 So we're calling our closure and then we're going to pass in a string called string. 22 00:02:03,670 --> 00:02:07,720 And the closure, as you can see, is completely happy with that. 23 00:02:07,900 --> 00:02:18,160 But what if we try to pass in a number now, to example, will we see the two is underlined in red because 24 00:02:18,160 --> 00:02:22,480 it is expecting a string which was the first type that was inferred. 25 00:02:22,480 --> 00:02:30,850 So we can see that by hovering over it and it says expected string found an integer and that's really 26 00:02:30,850 --> 00:02:34,900 all there is to it for closure type annotations. 27 00:02:35,020 --> 00:02:40,330 So now I want to take a quick minute to discuss closures performance. 28 00:02:40,570 --> 00:02:47,380 Russ is closures are designed to be fast closures are not allocated on the heap unless you put them 29 00:02:47,380 --> 00:02:50,170 in some kind of a container such as a vector. 30 00:02:51,720 --> 00:02:59,460 And since each closure has a known type, whenever Rust compiles the code, it can inline that code 31 00:02:59,460 --> 00:03:02,070 for that particular closure. 32 00:03:02,070 --> 00:03:08,730 And lining is a technique where the compiler will add the closure inside the calling functions block. 33 00:03:09,000 --> 00:03:14,610 And this prevents another separate function call from happening, which is going to give us a performance 34 00:03:14,610 --> 00:03:15,660 optimization. 35 00:03:15,870 --> 00:03:22,830 So if you are creating a program that is extremely performance dependent, closures are still very acceptable 36 00:03:22,860 --> 00:03:26,010 to use in the right situation.