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 comment