Опциональный параметры и параметры по-умолчанию в функциях и методах в Swift

Данным постом начинаю рубрику изучения swift.
Делается больше для себя и “чтобы не забыть”.
Плюс ко всему написание поста хорошо помогает закрепить прочитанное и испробованное.
Итак. Есть несколько вариантов написания функций и методов с опциональными значениями параметров.

Примеры взяты отсюда.

Первый вариант прост до безобразия и настолько же мерзок. Дублирование кода и перегрузка функций, которые я не люблю еще со времен института. Позволяет писать огромные портянки кода. Вариант особенно хорош, если вам платят за количество написанных строчек. Пишете десяток перегрузок функций и дело в шляпе. Придумано видимо именно для этого. Другого логического объяснения я пока не нашел, но на вкус и цвет, как говорится. Удачного дебага, сучки.

func printFirstName(firstName:String) {
    println(firstName)
}
func printFirstName(firstName:String,surname:String) {
    println("\(firstName) \(surname)")
}
printFirstName("Joe") //prints Joe
printFirstName("Joe", "Blow") //prints Joe Blow

Вариант второй отличается от первого тем, что внутри функции происходит магия по вычислению “А что у нас там со вторым параметром?”. Не сильно лучше первого варианта, когда необходимо сообщать функции, что у нас все по нулям. Особенно это печалит, когда на входе много параметров, но метод все же лучше, чем первый (по моему субъективному мнению). В общем – выигрыша никакого за исключением того, что теперь можно указать в параметре nil и все будут счастливы.

func printFirstName(firstName:String,surname:String?) {
    if let unwrappedSurname = surname {
        println("\(firstName) \(unwrappedSurname)")
    } else {
        println(firstName)
    }
 
}
printFirstName("Joe",nil)    //prints Joe
printFirstName("Joe", "Blow")    //prints Joe Blow

Добавляется знак вопроса после обозначения типа параметра, который намекает нам, что данный параметр вовсе и не обязателен. Но указывать его при вызове функции все же придется – иначе рантайм еррор.

И третий вариант – мой любимый.

func printFirstName(firstName:String,surname:String?=nil) {
    if let unwrappedSurname = surname {
        println("\(firstName) \(unwrappedSurname)")
    } else {
        println(firstName)
    }
     
}
printFirstName("Joe")    //prints Joe
printFirstName("Joe", surname: "Blow")    //prints Joe Blow

Чувствуете разницу? Единственное “но”, которое даже и не “но” вовсе, а повышает читаемость кода – это необходимость указывать название передаваемого параметра.

Можно писать так:

func myMegaFunction(param1: String?=nil, param2: String?=nil, param3: Int?=nil, param4: Int?=nil){
   //some logic
}

myMegaFunction(param1: "param1Value", param2: "param2Value", param3: 3)

Еще один плюс, который лично мне по душе – возможность переставлять параметры местами при вызове. Например:

myMegaFunction(param2: "param2Value", param3: 3, param1: "param1Value")

Вызывает привыкание и потом очень не хватает данного функционал в других языках.