This post has been updated for Swift 3.0 here.
This post has been updated for Swift 3.0 here.
There are some changes in Swift 2.0 to Optional Function parameters, so I thought I should revisit this blog post.
For info just on function parameters in Swift 2.0, click on my post here.
Swift has an interesting multi-pronged approach to dealing with default and optional function parameters, based in part on its relationship with Objective C and part inspired by other approaches.
It’s worth exploring the options.
Optional function parameters approach 1
First of all, let’s look at one approach to optional parameters:
func printFirstName(firstName:String) { print(firstName) } func printFirstName(firstName:String,surname:String) { print("\(firstName) \(surname)") } printFirstName("Joe") //prints Joe printFirstName("Joe", surname: "Blow") //prints Joe Blow
Wait – there are two functions with the same name? And why is the second function called printFirstName, when it clearly has a parameter called ‘surname’?
Well this is the same approach Objective C took, where the function wasn’t just defined by its name, but its parameters as well. So we have two functions – one is ‘printFirstName(firstName)’ and the other is printFirstName(firstName,surname)
Parameters with default values approach 1
This technique can also be a way to define default parameters, where the function with less parameters can call the function with extra parameters, defining defaults.
func printFirstName(firstName:String) { printFirstName(firstName,surname: "Smith") } func printFirstName(firstName:String,surname:String) { print("\(firstName) \(surname)") } printFirstName("Joe") //prints Joe Smith printFirstName("Joe", surname: "Blow") //prints Joe Blow
This technique of optional parameters is consistent with the approach Objective C took and was necessary to include in Swift to be able to interpret underlying Objective C code. (I discussed optional parameters in Objective C in a previous blog post here).
Optional function parameters approach 2
As Swift has an Optional variable type, making a parameter Optional, would obviously make it optional 😉 However this doesn’t mean you don’t need to pass anything – you still need to pass nil, and deal with checking the optional contains something in the function.
func printFirstName(firstName:String,surname:String?) { if let surname = surname { print("\(firstName) \(surname)") } else { print(firstName) } } printFirstName("Joe", surname: nil) //prints Joe printFirstName("Joe", surname: "Blow") //prints Joe Blow
Parameters with default values approach 2
Somewhere along the beta line, the Swift engineers made the brilliant decision to introduce true default values for parameters. Parameters with default values have a few special attributes:
- to be called in a different order, they need to be declared after any parameters without default values
- These parameters with defaults can be left out when calling the function
- If external parameter names are included (the second parameter onwards have external parameter names by default) parameters can be included in any order!
Note: In this example the first parameter specifies an external parameter name so as to be able to called out of order.
func printName(firstName firstName:String="Joe",middleName:String="Andrew",surname:String="Blow") { print("\(firstName) \(middleName) \(surname)") } printName(firstName: "John", middleName: "Juan", surname: "Smith") //prints John Juan Smith printName(firstName: "John") //middleName and surname parameters left out! prints John Andrew Blow printName() //prints all defaults (Joe Andrew Smith) printName(surname: "Smith", middleName: "Julius", firstName: "John") //parameters out of order! prints John Julius Smith
Optional function parameters approach 3
Which of course makes it possible for an ‘Optional’ variable to have a nil default value. So with a simple tweak to our previous default values example, we can introduce a true optional parameter, using the Optional type.
func printFirstName(firstName:String,surname:String?=nil) { if let surname = surname { print("\(firstName) \(surname)") } else { print(firstName) } } printFirstName("Joe") //prints Joe printFirstName("Joe", surname: "Blow") //prints Joe Blow
Be careful with naming conflicts mixing these approaches – if you have multiple functions with the same name but different parameters, and one of them has optional parameters, and there’s a possibility that Swift won’t know which function you’re referring to, there’s a naming conflict and the compiler will complain.
Good luck with your Swift functions, hopefully this has been helpful – let us know in comments any other function parameter tips. Swift 2.0 seems to be more forgiving and flexible and allow for some interesting combinations of functions with/without external parameter names and with/without default values.
For info just on function parameters in Swift 2.0, click on my post here.
Leave a Reply