Get introduced to the basic syntax for defining functions in Swift. Optionally specify different external parameter names or omit external names altogether at the call site.
- [Narrator] Functions are blocks of reusable code that perform a task. Functions can be defined as standalone global functions, or as methods of a type, such as a class. To repeat, methods are just functions of a type in Swift. And functions themselves are reference types. To define a function, write the func keyword, followed by the name of the function, such as, sayHelloWorld, a pair of parentheses to enclose the function's input parameters, if there are any, and curly braces to enclose the function's body. Even if there are no parameters, empty parentheses must still be written.
And the naming convention is to use camel casing, beginning with a lowercase letter. Then, in the body of the function, write one or more statements to execute when the function is called, such as, printing hello world. Parameters are written as name type pairs, similar to how you explicitly declare a variable, or constant type. Functions can have no parameters, as I just showed you, or, they can have one or more parameters. I'll define a sayHelloTo function. It will take a parameter name of type string, and then print hello to that name. Functions can also have multiple parameters, separated by commas in the parameter list.
I'll define a function say, that takes two parameters, greeting of type string, and to, also of type string. And say will just print the greeting to the to. Now I'll call that function. What is displayed when you call a function is called the external parameter name. What a parameter is referred to internally within the function is called the local parameter name. A function's parameters automatically have the same external and local parameter names by default. And notice that when you call a function, the first parameter name is displayed.
If you're coming from Swift 2, you are used to the first parameter being automatically omitted. Now, if you want to ignore the first parameter at the call site, you must explicitly ignore it, by writing an underscore before the parameter name in the definition. And I'll accept the Fix-it suggestion to remove the first parameter in the call. Writing the underscore before a parameter name explicitly suppresses displaying that name externally. So now this function reads nicely at the call site. Say goodbye to Hollywood. But using the word to internally for the local parameter name is not ideal.
To what? You can explicitly define an external parameter name for a parameter by writing it before the local parameter name in the parameter list. If you do, that external name will be displayed when calling the function instead, while the local parameter name will be available within the function. For example, I'll use to for the external name and name for the local parameter name. Functions can optionally return a value. To indicate that a function does return a value, write the return arrow, a hyphen and a right angle bracket, followed by the type of the return value, after the parameter list and before the opening curly brace.
I'll define an add function that takes two Int parameters and returns an Int. The results of adding a + b is passed back from the function using the return keyword. And notice that I explicitly omitted the external parameter names from both parameters by writing underscores. So, calling add only takes a comma separated list of two integer values with no parameter names displayed. This is all fine and good, except callers can't tell by the function name just how many Int's they can pass to it. They might try to do this for example, (writes code) that's not going to work.
But there is a way to specify that a single parameter can take a variable number of values. This is called a variadic parameter, and you define one by writing three periods after the parameter type in the function definition. A variadic parameter can take zero or more instances of the type specified in a comma separated list, which will be made available as an array of that type in the functions body. I'll use the reduce function to sum the Ints array values. Reduces first parameter is the initial value, which I've set to 0. And the second parameter is a combining operation.
I'm using the + operator. This combining operation is actually a closure. I'll get into those a little bit later on. So now when calling the add function with the variadic parameter, I can pass as many Int values in a comma separated list as I wish. The print function also happens to use a variadic parameter. I'll opt + click on it and show that the first parameter is a variadic parameter of any. Also, notice that the separator and terminator parameters have default values which is why I can optionally omit them when I'm calling print.
Parameters are constants by default, so they cannot be modified within the function body. If you want to mutate a parameter value, say from a variable that is defined before the function is called, write the inout keyword before the parameters type in the definition. If you're coming from Swift 2, take note that the inout declaration was moved from being a parameter name attribute to a type attribute in Swift 3. By marking the score parameter type as inout, the value will be copied in and noodable and the function will copy back and replace the original value with the mutated value.
I want to repeat that with inout parameter types, the value is copied in, mutated and then copied out, replacing the original value. You should not attempt to modify the original value, studentsScore in this case in the function body because those changes would be overwritten when the mutated value is copied back out. For this reason, only variables can be passed in to inout parameter types. And when calling a function with an inout parameter type, the value must be prefixed with an ampersand to indicate that it is being passed in as an inout parameter type. You might know from previous experience that prefixing a parameter with an ampersand is intended to convey that it is being passed by a reference.
And yet I just finished explaining that the value is copied in. In actuality, the value is being passed in at a memory address and it is actually passed in by reference. This is an optimization and implementation detail. Don't overthink things here. Think that the ampersand simply means the value can be modified by the function. And by the way, a functions function type is its input parameter types and its return type if it does return a value. The function type does not include the functions name or parameter names. So, add is a function type that takes a variadic Int parameter and returns an Int.
And apply(extraCredit toScore, is a function type that has two double parameters and does not return a value.
Learn how to write code, understand Swift's key concepts and best practices, and strengthen your programming problem-solving skills. Instructor Scott Gardner teaches the fundamentals, so you'll be prepared to develop applications for iOS, macOS, and other platforms. Completing this course will enable you to not only write first-class code, but to think like a Swift developer.
- Creating playgrounds
- Defining variables and constants
- Working with characters and strings
- Working with collections and groups
- Using operators and defining custom operators
- Controlling program flow
- Defining functions and closures
- Working with classes, structures, and enumerations
- Adopting protocols