1 00:00:00,350 --> 00:00:03,760 It's possible to return multiple values from a single function. 2 00:00:03,760 --> 00:00:06,400 This is usually used to communicate errors. 3 00:00:06,400 --> 00:00:10,685 You set this up by declaring multiple return values within parentheses, 4 00:00:10,685 --> 00:00:14,772 following the parentheses that accept parameters for the function. 5 00:00:14,772 --> 00:00:19,861 So here, we specify that this squareRoot function is going to return one value 6 00:00:19,861 --> 00:00:24,658 that's a float64 type, and then a second value that's an error type. 7 00:00:24,658 --> 00:00:26,282 Now, as you might be aware, 8 00:00:26,282 --> 00:00:30,010 it's not possible to take a square root of a negative number. 9 00:00:30,010 --> 00:00:32,690 So, we've set our square root function up to check for this. 10 00:00:32,690 --> 00:00:36,490 It looks at the parameter that got passed in, x, and 11 00:00:36,490 --> 00:00:41,640 if it's less than 0 then we return the value 0, which we're going to ignore. 12 00:00:41,640 --> 00:00:47,660 As well as the new error value, which we get by calling the format packages Errorf 13 00:00:47,660 --> 00:00:52,200 function, and passing it a string, can't take the square root of a negative number. 14 00:00:53,520 --> 00:00:58,490 If x is greater than 0, or equal to 0, then we'll proceed as normal. 15 00:00:58,490 --> 00:01:01,580 We call the math packages square root function and 16 00:01:01,580 --> 00:01:05,090 pass it the parameter that we got. 17 00:01:05,090 --> 00:01:09,340 We then return the value nil, which represents that we have no error. 18 00:01:09,340 --> 00:01:13,640 We then handle those multiple return values up here in the main function. 19 00:01:14,800 --> 00:01:17,460 We call square root, up here, and 20 00:01:17,460 --> 00:01:21,830 then we assign two variables at once based on its return value. 21 00:01:21,830 --> 00:01:25,702 The square root variable will hopefully contain the square root of whatever 22 00:01:25,702 --> 00:01:27,467 argument we pass the square root. 23 00:01:27,467 --> 00:01:30,400 And the error value will hopefully be nil. 24 00:01:30,400 --> 00:01:34,692 But in the event that there was a problem, say if we were to call square 25 00:01:34,692 --> 00:01:38,928 root with a negative number, the error value will not be nil. 26 00:01:38,928 --> 00:01:45,950 We'll have passed the return value of this error f function, 27 00:01:45,950 --> 00:01:50,680 which will be an error value, which will then logout to the console. 28 00:01:50,680 --> 00:01:55,810 Calling the fatal function from the log packages cause 29 00:01:55,810 --> 00:01:59,010 your program to print an error message and then exit immediately. 30 00:01:59,010 --> 00:02:03,090 So this line down here would never be reached if there was an error. 31 00:02:03,090 --> 00:02:04,840 So, we handled the error here and 32 00:02:04,840 --> 00:02:10,060 in the event that there's not an error we proceed to print out the square root. 33 00:02:10,060 --> 00:02:11,100 So let's try running this. 34 00:02:13,320 --> 00:02:17,100 Okay, and because we called square root with a negative number we see 35 00:02:17,100 --> 00:02:21,860 our error message printed out here, can't take square root of a negative number. 36 00:02:21,860 --> 00:02:27,804 Where as if we were to change this to a valid value say get the square root of 9, 37 00:02:27,804 --> 00:02:31,828 if we try running this again it runs successfully and 38 00:02:31,828 --> 00:02:34,587 it prints out our square root, 3. 39 00:02:34,587 --> 00:02:37,522 These function calls also return multiple values. 40 00:02:37,522 --> 00:02:41,894 But in this case we're getting a compile error because we aren't doing anything 41 00:02:41,894 --> 00:02:46,526 with the second value We're getting the multiple value os.Stat() in single value 42 00:02:46,526 --> 00:02:48,030 context. 43 00:02:48,030 --> 00:02:53,350 We can get this code to compile by adding the blank identifier. 44 00:02:53,350 --> 00:02:56,450 This will assign the second value, the error value, 45 00:02:56,450 --> 00:03:02,070 from os.Stat to a throwaway variable, this underscore that you see here. 46 00:03:04,010 --> 00:03:07,387 So if we have this down here as well our program will then compile and run. 47 00:03:07,387 --> 00:03:13,202 So as you can see up here that we get a file 48 00:03:13,202 --> 00:03:18,740 size for the existent text file. 49 00:03:18,740 --> 00:03:23,886 However down here we get a run time panic, this is a special type of 50 00:03:23,886 --> 00:03:29,612 error that occurs after your program compiles and while it's running. 51 00:03:29,612 --> 00:03:32,790 And that's something that you want to avoid wherever possible. 52 00:03:32,790 --> 00:03:36,973 And this is why that assigning error values to the blank identifier isn't 53 00:03:36,973 --> 00:03:38,130 always a good idea. 54 00:03:38,130 --> 00:03:42,975 In this case, checking the size of the existent.txt file worked 55 00:03:42,975 --> 00:03:48,190 because that file was on the disk, but, nonexistent.txt wasn't. 56 00:03:48,190 --> 00:03:53,131 And therefore we got an error which we ignored and when we tried to print 57 00:03:53,131 --> 00:03:59,020 out the size on this invalid file info object, our program panicked. 58 00:03:59,020 --> 00:04:03,670 We can fix this by checking to see if the error return value from os.stat 59 00:04:03,670 --> 00:04:05,180 is anything other than nil. 60 00:04:05,180 --> 00:04:07,600 And if it is, handling the error. 61 00:04:07,600 --> 00:04:09,590 So instead of the blank identifier here, 62 00:04:09,590 --> 00:04:14,540 let's assign this error return value to a variable called error. 63 00:04:14,540 --> 00:04:16,580 And here let's do a test. 64 00:04:16,580 --> 00:04:21,400 Let's say if the error Is not equal to nil. 65 00:04:24,930 --> 00:04:27,870 Then we will print out the error. 66 00:04:31,287 --> 00:04:35,340 And if the error is nil, it means that we got our file info back successfully. 67 00:04:35,340 --> 00:04:40,180 So we can move this format print line file info. 68 00:04:40,180 --> 00:04:44,210 Size line up into the else clause. 69 00:04:47,030 --> 00:04:50,740 And we'll be able to print the file info out successfully. 70 00:04:50,740 --> 00:04:56,220 We'll do the same down here following getting os.stat for the second file. 71 00:04:56,220 --> 00:05:00,410 We need to be sure to assign not to the blank Identifier, 72 00:05:00,410 --> 00:05:02,130 but to the error variable. 73 00:05:03,300 --> 00:05:04,660 We'll test if it's nil. 74 00:05:04,660 --> 00:05:06,540 If it's not nil, we'll print out the error. 75 00:05:06,540 --> 00:05:08,610 Otherwise, we'll print out the file info. 76 00:05:09,650 --> 00:05:12,361 Now let's try running this again. 77 00:05:12,361 --> 00:05:15,954 And you see for our first file we got a file size of 0, 78 00:05:15,954 --> 00:05:19,320 which, because it does exist but its size is 0. 79 00:05:19,320 --> 00:05:22,330 And for the second file it prints out our error. 80 00:05:22,330 --> 00:05:26,330 It tried to run stats on nonexistant.txt, but there was no such file.