Swift işlevinde varsayılan isteğe bağlı parametre


109

firstThingVarsayılana ayarladığımda , nilbu çalışacak, varsayılan değeri olmadan nilişlevi çağırırken eksik bir parametrenin olduğuna dair bir hata alıyorum.

Yazarak , Int?varsayılan bir değerle isteğe bağlı hale getirdiğini düşündüm nil, değil mi? Ve eğer öyleyse, neden olmadan çalışmıyor = nil?

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

1
Varsayılan değere sahip parametre func test(firstThing: Int = 4)olmayan bir yazabileceğinizi düşünün Optional. Optional(Ne olduğu tip ?bir tür adı genişletir olarak) bir değer türüdür; "isteğe bağlı parametre", türüne bakılmaksızın bir işlev çağrısında bulunabilen veya bulunmayan bir parametre için talihsiz bir isimdir.
zneak

Bu kodu test etmek için Swift'in hangi sürümünü kullandınız? Kodunuz iyi çalışıyor !! İsteğe bağlı sadece bir türdür ve varsayılan parametreler,
Swift'deki

Yanıtlar:


212

Opsiyonel ve varsayılan parametreler iki farklı şeydir.

İsteğe bağlı bir değişkendir nil, işte bu kadar.

Varsayılan parametreler , bu parametreyi atladığınızda varsayılan bir değer kullanır, bu varsayılan değer şu şekilde belirtilir:func test(param: Int = 0)

İsteğe bağlı bir parametre belirtirseniz, geçirmek istediğiniz değer olsa bile bunu sağlamanız gerekir nil. İşleviniz böyle görünüyorsa func test(param: Int?), böyle arayamazsınız test(). Parametre isteğe bağlı olsa da, varsayılan bir değeri yoktur.

Ayrıca iki birleştirmek ve isteğe bağlı alan bir parametre olabilir nilböyle varsayılan değer şöyledir: func test(param: Int? = nil).


30
"İsteğe bağlı bir parametre belirtirseniz, bunu sağlamanız gerekir". Harika, teşekkürler Swift
andrewtweber

8
@andrewtweber Mizahınız takdir ediliyor, ancak yeni başlayanlar için, "İsteğe bağlı" ifadesinin bir nesne veya değer sağlama anlamına geldiğini açıklamanın yararlı olabileceğini düşündüm. Bunu yapmak zorunda değilsiniz, bunun yerine nil (bir nesnenin veya değerin yokluğunu temsil eder) sağlayabilirsiniz. Sadece hangi seçeneği seçeceğinize karar vermelisiniz.
JD Sandifer

24

Varsayılan argüman, bir argüman iletmeden işlevi çağırmanıza izin verir. Bağımsız değişkeni iletmezseniz, varsayılan bağımsız değişken sağlanır. Yani kodunuzu kullanarak, bu ...

test()

... bununla tamamen aynıdır:

test(nil)

Varsayılan argümanı bu şekilde dışarıda bırakırsanız ...

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

... o zaman bunu artık yapamazsınız ...

test()

Bunu yaparsanız, tanımladığınız "eksik argüman" hatasını alırsınız. Her seferinde bir argüman geçirmelisiniz, bu argüman sadece nil:

test(nil)   // this works

19

Swift, parametreleri geçmeden bir işlevi çağırabileceğiniz ve yine de çağrılacağı JavaScript gibi diller gibi değildir. Swift bir işlevi çağırmak için Yani, gerek için, parametrelerine bir değer atamanız .

Parametrelerin varsayılan değerleri, işlevi çağırırken belirtmeden bir değer atamanıza izin verir. Bu yüzdentest() , testin bildiriminde varsayılan bir değer belirlediğinizde çalışır.

O varsayılan değeri dahil etmezseniz, size çağrı üzerine değer sağlamanız gerekir: test(nil).

Ayrıca, bu soruyla doğrudan ilgili değil, ancak muhtemelen not etmeye değer, Swift'deki olası sıfır opsiyonları ile başa çıkmak için muhtemelen boş işaretçilerle başa çıkmanın "C ++" yolunu kullanıyorsunuz. Aşağıdaki kod daha güvenlidir (özellikle çok iş parçacıklı yazılımda) ve isteğe bağlı olanın zorla açılmasını önlemenizi sağlar:

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

8

Sen conflating olan Optionalbir varsayılan sahip. An Optional, bir değeri veya nil'i kabul eder. Bir varsayılana sahip olmak, işlevi çağırırken bağımsız değişkenin atlanmasına izin verir. Bir bağımsız değişkenin Optionaltürü olsun veya olmasın varsayılan bir değeri olabilir .

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

    print("param2 = \(param2)")

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

Çıkışlı örnek çağrılar:

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

Özetlemek:

  • İle yazın? (ör. String?) bir Optionalsıfır olabilir veya bir Tür örneği içerebilir
  • Varsayılan değere sahip bağımsız değişken bir işlev çağrısından çıkarılabilir ve varsayılan değer kullanılır
  • Her ikisi de Optionalve varsayılana sahipse, bu durumda işlev çağrısından çıkarılabilir VEYA dahil edilebilir ve bir sıfır değeri ile sağlanabilir (örneğin, param1: nil)

let veya var gibi bir değişken olarak varsayılan parametreyi ekleyebilir miyim? Teşekkürler
Yogesh Patel

@YogeshPatel Ne demek istediğinizden emin değilim.
Chuck Krutsinger

var myName = "Yogesh" gibi. Şimdi benim fonksiyonum 1. func getFilterNames (isim: string = myName) {} gibi bu yaklaşım benim için çalışmıyor. 2. func getFilterNames (name: string = "Yogesh") {} bu yaklaşım benim için çalışıyor. Ama ben ilkini istiyorum, lütfen bunu başarmama yardım edebilir misin? Çok teşekkürler!
Yogesh Patel

@YogeshPatel Sanırım isteyebileceğiniz şey func getFilterNames(name: inout String){ }, aktarılan adı değiştirmenize izin verecek.
Chuck Krutsinger

Hayır, hayır efendim. parametremde değişiklik yapmak istemiyorum. parametrem için varsayılan değer vermek istiyorum, ancak statik "Yogesh" gibi değil. let name = "Yogesh" dinamik func getFilterNames (name: string = name) böyle yapmak istiyorum. anlıyor musunuz efendim? Teşekkürler!
Yogesh Patel

4

bir bool parametresi kullanmanız gerektiğinde, sadece varsayılan değeri atamanız gerekir.

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

sonra param olmadan veya param ile kullanabilirsiniz:

test() //here flag automatically has the default value: false
test(WithFlag: true) //here flag has the value: true

Buna olumsuz oy veren insanlar için bunun yerine yanlış şeyi düzeltebilirsiniz, böylece diğerleri anlayacaktır.
Niib Fouda

3

"İsteğe bağlı parametre", "bu parametrenin türünün isteğe bağlı olduğu" anlamına gelir. Bu, "Bu parametre isteğe bağlıdır ve bu nedenle işlevi çağırdığınızda göz ardı edilebilir" anlamına gelmez.

"İsteğe bağlı parametre" terimi kafa karıştırıcı görünüyor. Açıklığa kavuşturmak gerekirse, "isteğe bağlı parametre" yerine "isteğe bağlı tür parametresi" demek daha doğrudur, çünkü buradaki "isteğe bağlı" kelimesi yalnızca parametre değerinin türünü açıklamak içindir, başka hiçbir şey ifade etmez.


0

funcParametre ile veya parametresiz olarak çağırabilmek istiyorsanız func, diğerini çağıran aynı isimden bir ikinci yaratabilirsiniz .

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

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

şimdi adı testparametresiz veya parametresiz bir işlevi çağırabilirsiniz .

// both work
test()
test(firstThing: 5)

Parametre için varsayılan değer olarak sadece nil belirleyebildiğiniz halde neden ek bir işlev tanımlayasınız?
Peter Schorn

-1

O parametre için isteğe bağlı parametre ile varsayılan değeri birleştirmeye çalıştığınızda biraz yanıltıcıdır. Bunun gibi,

func test(param: Int? = nil)

Bu ikisi tamamen zıt fikirlerdir. İsteğe bağlı bir tür parametreniz olduğunda ancak buna varsayılan değer de sağladığınızda, varsayılan bir değere sahip olduğu için artık isteğe bağlı bir tür değildir. Varsayılan değer sıfır olsa bile, swift isteğe bağlı bağlamayı varsayılan değerin ne olduğunu kontrol etmeden kaldırır.

Bu nedenle, varsayılan değer olarak nil kullanılmaması her zaman daha iyidir.


1
Bu yanlış. Varsayılan bir değere (çift nil) sahip bir isteğe bağlı olarak yanlış bir şey yoktur .
Brian Kendig

Demek istediğim, bir değişkenin varsayılan bir değeri olduğunda, her zaman bir değere sahip olacağı anlamında isteğe bağlı değildir.
Shubham Naik

1
Bu doğru değil ve neyi tarif etmeye çalıştığından emin değilim. Bir değişkenin kendisine atanan bir değeri olduğunda, her zaman atanacağını doğru söylüyorsunuz; Boşluğunu kaldırmadıkça atamasını kaldıramazsınız (ya da yapmak istemezsiniz). Ve bir değişkeni bir değere sahip olmadan önce kullanmaya çalışırsanız (olduğu gibi var foo: String; print(foo)) Swift size bir derleme hatası verecektir . Ancak varsayılan değere sahip bir işlev bağımsız değişkeni isteğe bağlı bir bağımsız değişkendir (işlev çağrısında iletmeniz gerekmez) ve isteğe bağlı tipte de olabilir ( nilvarsayılan değer olarak atanmasına izin verir ).
Brian Kendig

İsteğe bağlı, esasen bir birleşim türüdür <Type | Nil>, yani Belirtilen tipe veya Sıfır Tipine sahip olabilir. (Swift'in Sendikaları olduğunu varsayarsak, ki yok, ama burada kavramsal olarak konuşuyoruz). yani Int? = nil tamamen iyidir.
Shayne

-1

Varsayılan değer, veri türünün varsayılan değeri anlamına gelmez. Burada varsayılan değer, işlevin tanımlanması sırasında tanımlanan değer anlamına gelir. fonksiyonda değişkeni tanımlarken değişkenin öntanımlı değerini beyan etmeliyiz.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.