Необязательный параметр по умолчанию в функции Swift

109

Когда я установил firstThing значение по умолчанию, nilэто будет работать, без значения по умолчанию nilя получаю сообщение об ошибке при вызове функции.

Печатая, Int?я подумал, что он стал необязательным со значением по умолчанию nil, я прав? И если да, то почему не работает без = nil?

func test(firstThing: Int? = nil) {
    if firstThing != nil {
        print(firstThing!)
    }
    print("done")
}
test()
РикБрунштедт
источник
1
Учтите, что вы можете написать func test(firstThing: Int = 4): не Optionalпараметр со значением по умолчанию. OptionalТип (который является то , что ?в имени типа расширяется в) представляет собой тип значения; «необязательный параметр» - неудачное имя для параметра, который может присутствовать или не присутствовать при вызове функции, независимо от его типа.
zneak
Какую версию Swift вы использовали для тестирования этого кода? Ваш код отлично работает !! Необязательные - это просто тип, а параметры по умолчанию отлично работают, как и с другим типом в Swift
Виктор Сиглер,

Ответы:

212

Опции и параметры по умолчанию - это разные вещи.

Необязательный параметр - это переменная, которая может быть nil , вот и все.

Параметры по умолчанию используют значение по умолчанию, когда вы опускаете этот параметр, это значение по умолчанию указывается следующим образом:func test(param: Int = 0)

Если вы указываете параметр, который является необязательным, вы должны предоставить его, даже если значение, которое вы хотите передать, равно nil. Если ваша функция выглядит так func test(param: Int?), вы не можете называть ее так test(). Несмотря на то, что параметр является необязательным, у него нет значения по умолчанию.

Кроме того, можно объединить два и иметь параметр , который принимает необязательный , где nilэто значение по умолчанию, например: func test(param: Int? = nil).

Эмилио Пелаес
источник
30
«Если вы укажете необязательный параметр, вы должны его указать». Отлично, спасибо Swift
andrewtweber
8
@andrewtweber Мы ценим ваш юмор, но я подумал, что для новичков было бы полезно уточнить, что «Необязательно» относится к предоставлению объекта или значения. Вам не обязательно этого делать, вместо этого вы можете указать nil (что означает отсутствие объекта или значения). Вам просто нужно решить, какой вариант вы выберете.
JD Sandifer
24

Аргумент по умолчанию позволяет вызывать функцию без передачи аргумента. Если вы не передадите аргумент, будет предоставлен аргумент по умолчанию. Итак, используя ваш код, это ...

test()

... точно так же, как это:

test(nil)

Если вы оставите такой аргумент по умолчанию ...

func test(firstThing: Int?) {
    if firstThing != nil {
        print(firstThing!)
    }
    print("done")
}

... тогда ты больше не сможешь этого делать ...

test()

Если вы это сделаете, вы получите описанную вами ошибку «отсутствует аргумент». Вы должны передавать аргумент каждый раз, даже если это справедливый аргумент nil:

test(nil)   // this works
Аарон Расмуссен
источник
19

Swift не похож на языки вроде JavaScript, где вы можете вызывать функцию без передачи параметров, и она все равно будет вызываться. Итак, чтобы вызвать функцию в Swift, вам нужно присвоить значение ее параметрам.

Значения по умолчанию для параметров позволяют присваивать значение без его указания при вызове функции. Вот почему test()работает, когда вы указываете значение по умолчанию в объявлении теста.

Если вы не включили это значение по умолчанию, вам необходимо указать значение при вызове: test(nil) .

Кроме того, и это не имеет прямого отношения к этому вопросу, но, вероятно, стоит отметить, что вы используете способ «C ++» работать с возможно нулевыми указателями для работы с возможными нулевыми опциями в Swift. Следующий код более безопасен (особенно в многопоточном ПО) и позволяет избежать принудительного развертывания необязательного:

func test(firstThing: Int? = nil) {
    if let firstThing = firstThing {
        print(firstThing)
    }
    print("done")
}
test()
nbloqs
источник
8

Вы путаетесь Optionalсо значением по умолчанию. An Optionalпринимает значение или ноль. Наличие значения по умолчанию позволяет опустить аргумент при вызове функции. Аргумент может иметь значение по умолчанию с Optionalтипом или без него .

func someFunc(param1: String?,
          param2: String = "default value",
          param3: String? = "also has default value") {
    print("param1 = \(param1)")

    print("param2 = \(param2)")

    print("param3 = \(param3)")
}

Примеры вызовов с выводом:

someFunc(param1: nil, param2: "specific value", param3: "also specific value")

param1 = nil
param2 = specific value
param3 = Optional("also specific value")

someFunc(param1: "has a value")

param1 = Optional("has a value")
param2 = default value
param3 = Optional("also has default value")

someFunc(param1: nil, param3: nil)

param1 = nil
param2 = default value
param3 = nil

Подвести итоги:

  • Типа с? (например, String?) Optionalможет иметь значение nil или может содержать экземпляр типа
  • Аргумент со значением по умолчанию может быть опущен при вызове функции, и будет использоваться значение по умолчанию.
  • Если оба Optionalи имеют значение по умолчанию, то его можно опустить при вызове функции ИЛИ может быть включено и может быть предоставлено значение nil (например, param1: nil)
Чак Крутингер
источник
Могу ли я добавить параметр по умолчанию в качестве переменной, например let или var? Спасибо
Йогеш Патель
@YogeshPatel Не уверен, что вы имеете в виду.
Чак Крутингер,
например var myName = "Yogesh". Теперь моя функция похожа на 1. func getFilterNames (name: string = myName) {} этот подход у меня не работает. 2. func getFilterNames (name: string = "Yogesh") {} этот подход мне подходит. Но я хочу сначала, так что не могли бы вы помочь мне в этом. Большое спасибо!
Йогеш Патель,
@YogeshPatel Я думаю, что вам может понадобиться то, func getFilterNames(name: inout String){ }что позволит вам изменить переданное имя.
Чак Крутингер,
Нет, сэр. я не хочу изменять свой параметр. Я просто хочу дать своему параметру значение по умолчанию, но не как статический «Йогеш». я хочу сделать как let name = "Yogesh" динамическая функция getFilterNames (name: string = name) вот так. получаете это сэр? Спасибо!
Йогеш Патель,
4

если вам нужно использовать параметр bool, вам нужно просто назначить значение по умолчанию.

func test(WithFlag flag: Bool = false){.....}

тогда вы можете использовать без параметра или с параметром:

test() //here flag automatically has the default value: false
test(WithFlag: true) //here flag has the value: true
Нииб Фуда
источник
Для людей, которые проголосовали против этого, вы можете исправить неправильную вещь, чтобы другие поняли.
Niib Fouda
3

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

Термин «необязательный параметр» сбивает с толку. Чтобы уточнить, точнее будет сказать «необязательный параметр типа» вместо «необязательный параметр», поскольку слово «необязательный» здесь предназначено только для описания типа значения параметра и ничего больше.

Todanley
источник
0

Если вы хотите иметь возможность вызывать funcс параметром или без него, вы можете создать второй funcс тем же именем, который вызывает другой.

func test(firstThing: Int?) {
    if firstThing != nil {
        print(firstThing!)
    }
    print("done")
}

func test() {
    test(firstThing: nil)
}

теперь вы можете вызывать функцию с именем testбез параметра или без него.

// both work
test()
test(firstThing: 5)
Шон256
источник
Зачем определять дополнительную функцию, если можно просто указать nil в качестве значения по умолчанию для параметра?
Питер Шорн,
-1

Это немного сложно, когда вы пытаетесь объединить необязательный параметр и значение по умолчанию для этого параметра. Как это,

func test(param: Int? = nil)

Это две совершенно противоположные идеи. Когда у вас есть необязательный параметр типа, но вы также предоставляете ему значение по умолчанию, теперь он больше не является необязательным типом, поскольку он имеет значение по умолчанию. Даже если по умолчанию установлено значение nil, swift просто удаляет необязательную привязку без проверки значения по умолчанию.

Поэтому всегда лучше не использовать nil в качестве значения по умолчанию.

Шубхам Наик
источник
1
Это неверно. Нет ничего плохого в том, что необязательный параметр имеет значение по умолчанию (даже nil).
Брайан Кендиг,
Я говорю, что если переменная имеет значение по умолчанию, она не является необязательной в том смысле, что она всегда будет иметь значение.
Шубхам Наик
1
Это неправда, и я не уверен, что вы пытаетесь описать. Я думаю, вы правильно говорите, что если переменной присвоено значение, она всегда будет назначаться; вы не можете отменить его назначение (да и не захотели бы этого), если не освободите его. И Swift выдаст вам ошибку компиляции, если вы попытаетесь использовать переменную до того, как она получит значение (как в var foo: String; print(foo)). Но аргумент функции со значением по умолчанию является необязательным аргументом (вам не нужно передавать его при вызове функции), и он также может быть необязательного типа (позволяя nilназначать ему значение по умолчанию).
Брайан Кендиг
Необязательный параметр - это, по сути, тип объединения <Type | Nil>, т.е. он может иметь Указанный тип или Тип Nil. (Предполагая, что у swift были Unions, чего нет, но мы говорим здесь концептуально). так инт? = nil прекрасно.
Shayne
-1

Значение по умолчанию не означает значение по умолчанию для типа данных. Здесь значение по умолчанию - среднее значение, определенное во время определения функции. мы должны объявить значение переменной по умолчанию при определении переменной в функции.

Махеш Кулкарни
источник