1 00:00:00,520 --> 00:00:02,440 Let's write a new function. 2 00:00:02,440 --> 00:00:09,560 The standard library already has a swap function, so we'll call ours swapValues. 3 00:00:09,560 --> 00:00:14,110 Now, unlike anything we've done before, right after the name of the function, 4 00:00:14,110 --> 00:00:18,920 we're going to add, between a set of angle brackets, the letter T. 5 00:00:20,550 --> 00:00:23,820 There shouldn't be any spaces between the name of the function and 6 00:00:23,820 --> 00:00:25,370 the angle bracket. 7 00:00:25,370 --> 00:00:28,460 Now, we've always said that when writing functions immediately after 8 00:00:28,460 --> 00:00:31,440 the function name, we put our argument list, but 9 00:00:31,440 --> 00:00:34,060 here is the first time we're doing something different. 10 00:00:34,060 --> 00:00:38,800 Now, after the angle brackets, next, let's add the argument list like we usually do. 11 00:00:38,800 --> 00:00:42,425 Since this is a swap function that swaps two values, again, 12 00:00:42,425 --> 00:00:45,660 we'll take two arguments, and we'll omit the external names, and 13 00:00:45,660 --> 00:00:48,610 fall the same convention as we've been doing. 14 00:00:48,610 --> 00:00:53,880 So the first argument name or local name is a, and we still want it 15 00:00:53,880 --> 00:00:59,990 to be an inout argument, or we wanna pass by reference, so add the inout keyword. 16 00:00:59,990 --> 00:01:02,910 Now, when do we set the type of a though? 17 00:01:02,910 --> 00:01:06,340 The type is going to be the letter T. 18 00:01:06,340 --> 00:01:10,700 Now, make sure it's an uppercase T, just like we've defined over here. 19 00:01:12,330 --> 00:01:16,488 Let's keep going, we'll add in a second argument, so 20 00:01:16,488 --> 00:01:23,230 omit the external name, we'll name it b locally, and inout again of type T. 21 00:01:23,230 --> 00:01:26,150 This is a generic function. 22 00:01:26,150 --> 00:01:30,630 A generic function uses a placeholder type name 23 00:01:30,630 --> 00:01:35,600 in place of an actual type name, which we've named T in this case. 24 00:01:35,600 --> 00:01:40,320 Note that T doesn't mean anything special, it's just a name. 25 00:01:40,320 --> 00:01:47,150 I can name this U, V, X, or even full words like value argument, or so on. 26 00:01:47,150 --> 00:01:53,680 T isn't a specific type, and this function doesn't say what T must be. 27 00:01:53,680 --> 00:01:57,400 I haven't specified whether it's a string or an int, but 28 00:01:57,400 --> 00:02:01,170 what the function does say that both a and 29 00:02:01,170 --> 00:02:06,072 b must be of the same type T, whatever T comes to represent. 30 00:02:06,072 --> 00:02:09,940 So what does that mean, whatever T comes to represent? 31 00:02:09,940 --> 00:02:11,700 You'll see in just a second. 32 00:02:11,700 --> 00:02:15,390 Now, the body of the function is the same as any other swap function, so 33 00:02:15,390 --> 00:02:21,360 you can just scroll up, grab this bit of code, hit Copy and Paste it in here. 34 00:02:21,360 --> 00:02:24,990 And that is our generic swap function, so let's use it. 35 00:02:26,000 --> 00:02:30,680 We're going to go down here, and we'll call swapValues, and 36 00:02:30,680 --> 00:02:35,320 pass in the variables d and e that we defined earlier, and 37 00:02:35,320 --> 00:02:39,830 you'll see from the results area of the playground that this works perfectly, and 38 00:02:39,830 --> 00:02:40,970 our values are being swapped. 39 00:02:41,990 --> 00:02:43,312 Okay, so we know that works. 40 00:02:43,312 --> 00:02:48,267 Let's call swapValues again, and 41 00:02:48,267 --> 00:02:53,660 now, we pass in g and h, and you'll see that it's been called twice. 42 00:02:53,660 --> 00:02:58,480 And if we go up here to where it's defined, it is back to being the original 43 00:02:58,480 --> 00:03:03,200 values, which means that it was swapped back after the call to swap string, so 44 00:03:03,200 --> 00:03:04,460 again, this works too. 45 00:03:05,540 --> 00:03:07,870 So what sorcery is this? 46 00:03:07,870 --> 00:03:12,527 In a generic function, the placeholder type, T, in this case, 47 00:03:12,527 --> 00:03:18,559 is replaced with an actual type when you call the function, important to remember. 48 00:03:18,559 --> 00:03:23,979 When we called swapValues the first time, and passed in d and e, everywhere 49 00:03:23,979 --> 00:03:29,314 in the function where we used T, which is in the argument list in this case, 50 00:03:29,314 --> 00:03:34,591 T gets replaced with int, since int is the argument type being passed in. 51 00:03:34,591 --> 00:03:38,519 The second time, we call it, since we pass in strings, 52 00:03:38,519 --> 00:03:41,460 T is replaced with a type string. 53 00:03:41,460 --> 00:03:44,252 If you tried to call swapValues, let's do that this time. 54 00:03:44,252 --> 00:03:49,755 So we'll call swapValues and we'll try to pass in d and then g, this will fail. 55 00:03:49,755 --> 00:03:51,066 If you read the error, 56 00:03:51,066 --> 00:03:56,870 you'll see it says cannot convert value of type String to expected argument type Int. 57 00:03:56,870 --> 00:04:01,790 This is because we said when defining the function, even though we don't know what T 58 00:04:01,790 --> 00:04:08,080 is, both a and b have to be the same type because they're both specified as T. 59 00:04:08,080 --> 00:04:11,910 When we pass in an int and a string, as we're doing here, 60 00:04:11,910 --> 00:04:18,240 since the first argument is int, T, the placeholder now represents the int type. 61 00:04:18,240 --> 00:04:22,420 This makes the argument type for the second argument int as well. 62 00:04:22,420 --> 00:04:25,420 A string is not an integer, so we get an error. 63 00:04:25,420 --> 00:04:26,760 Let me get rid of this. 64 00:04:28,280 --> 00:04:33,350 At the point of definition, the angle bracket T, line of code here, or 65 00:04:33,350 --> 00:04:38,660 bit of code, tells the compiler that this is a generic function and that 66 00:04:38,660 --> 00:04:44,100 T defines a placeholder type that will be specified when the function is called. 67 00:04:44,100 --> 00:04:47,890 T is more specifically called a type parameter. 68 00:04:47,890 --> 00:04:52,460 This way, when we specify the types of the arguments as T, when we're defining 69 00:04:52,460 --> 00:04:58,360 the function, the compiler knows to not go looking for an actual type called T. 70 00:04:58,360 --> 00:05:03,220 Type parameters can be used as the type for functions arguments as we've done. 71 00:05:03,220 --> 00:05:06,200 It can also be used as the function's return type, or 72 00:05:06,200 --> 00:05:09,150 to represent a type within the body of the function. 73 00:05:09,150 --> 00:05:13,830 Whatever the case, when the function is actually called the type parameters, and 74 00:05:13,830 --> 00:05:18,350 there can be more than one, will be replaced with an actual type. 75 00:05:18,350 --> 00:05:21,630 Now that we have a generic function, we can get rid of our 76 00:05:21,630 --> 00:05:25,970 two specific implementations, or three rather, we can get rid of swap any. 77 00:05:25,970 --> 00:05:32,350 We can get rid of swapString, and we can get rid of swapInts. 78 00:05:34,865 --> 00:05:40,180 swapValues works on both of these types, and even any type we have yet to define.