Bir değer olduğunu bildiğiniz için neden “Örtülü Olarak Açılmamış Seçenekler” oluşturmalısınız?


493

Neden yalnızca normal bir değişken veya sabit oluşturmak yerine "Örtülü Olarak Açılmamış İsteğe Bağlı" oluşturursunuz? Başarılı bir şekilde paketinin açılmış olabileceğini biliyorsanız, neden ilk önce bir isteğe bağlı oluşturmalısınız? Örneğin, neden:

let someString: String! = "this is the string"

daha yararlı olacaktır:

let someString: String = "this is the string"

”Opsiyonelleri, bir sabit veya değişkenin 'değersiz' olmasına izin verildiğini gösterirse”, ancak “bazen bir programın yapısından, isteğe bağlı olarak bu değer ilk ayarlandıktan sonra her zaman bir değere sahip olacağı açıktır”, ne anlama gelir? ilk etapta isteğe bağlı mı? Bir isteğe bağlı her zaman bir değere sahip olacağını biliyorsanız, bu isteğe bağlı değil mi?

Yanıtlar:


127

İnşa edilirken ve yapılandırılırken nil özelliklere sahip olabilen, ancak daha sonra değişmez ve nil olmayan bir nesne örneğini düşünün (NSImage genellikle bu şekilde tedavi edilir, ancak durumunda hala mutasyona uğrar). Örtük olarak açılmamış opsiyonel kodlar, nispeten düşük güvenlik kaybı ile kodunu iyi bir şekilde temizleyecektir (bir garanti olduğu sürece, güvenli olacaktır).

Açık olmak gerekirse: normal opsiyonlar neredeyse her zaman tercih edilir.


459

Örtük Olarak Açılmamış Seçenekler için kullanım durumlarını açıklayabilmeden önce, Swift'te Seçeneklerin ve Örtük Olarak Açılmamış Seçeneklerin ne olduğunu zaten anlamalısınız. Bunu yapmazsanız, önce isteğe bağlı makaleler hakkındaki makalemi okumanızı tavsiye ederim

Örtülü Olarak Açılmamış İsteğe Bağlı Ne Zaman Kullanılmalı

Birinin Örtük Olarak Açılmamış İsteğe Bağlı Olmasının iki ana nedeni vardır. Hepsinin asla erişilmeyecek bir değişken tanımlamasıyla ilgisi vardır, nilçünkü aksi takdirde Swift derleyicisi sizi her zaman açıkça bir İsteğe bağlı paketini açmaya zorlayacaktır.

1. Başlatma Sırasında Tanımlanamayan Bir Sabit

Başlatma işlemi tamamlandığında her üye sabiti bir değere sahip olmalıdır. Bazen, bir sabit başlatma sırasında doğru değeriyle başlatılamaz, ancak yine de erişilmeden önce bir değere sahip olması garanti edilebilir.

İsteğe bağlı bir değişken kullanıldığında, İsteğe bağlı otomatik olarak başlatıldığı nilve sonunda içereceği değer hala değiştirilemeyeceği için bu sorunla karşılaşılır . Ancak, nil olmadığından emin olduğunuz bir değişkeni sürekli olarak açmak bir acı olabilir. Örtülü Olarak Açılmamış Seçenekler, isteğe bağlı olarak, her yerde açıkça açmak zorunda kalmayacağı ek avantajla aynı faydaları elde eder.

Buna en iyi örnek, bir üye değişkenin görünüm yüklenene kadar bir UIView alt sınıfında başlatılamamasıdır:

class MyView: UIView {
    @IBOutlet var button: UIButton!
    var buttonOriginalWidth: CGFloat!

    override func awakeFromNib() {
        self.buttonOriginalWidth = self.button.frame.size.width
    }
}

Burada, görünüm yüklenene kadar düğmenin orijinal genişliğini hesaplayamazsınız, ancak görünümdeki awakeFromNibdiğer herhangi bir yöntemden önce çağrılacağını bilirsiniz (başlatma dışında). Değeri sınıfınızın her yerinde açık bir şekilde açılmaya zorlamak yerine, değeri Örtük Olarak Açılmamış İsteğe Bağlı olarak bildirebilirsiniz.

2. Uygulamanız Değişken Varlıktan Kurtarılamadığında nil

Bu son derece nadir olmalıdır, ancak bir değişkene nilerişildiğinde uygulamanız çalışmaya devam edemezse, test etmek için uğraşmak zaman kaybı olacaktır nil. Normalde, uygulamanızın çalışmaya devam etmesi için kesinlikle doğru olması gereken bir durumunuz varsa, bir assert. Örtük Olarak Açılmamış Bir İsteğe Bağlı, doğrudan içine yerleştirilmiş nil için bir iddiaya sahiptir. O zaman bile, isteğe bağlı olanın paketini açmak ve sıfırsa daha açıklayıcı bir iddia kullanmak genellikle iyidir.

Örtülü Olarak Paketlenmemiş Bir İsteğe Bağlı Ne Zaman Kullanılmamalıdır?

1. Tembel Hesaplanan Üye Değişkenleri

Bazen hiçbir zaman sıfır olmaması gereken bir üye değişkeniniz olabilir, ancak başlatma sırasında doğru değere ayarlanamaz. Çözümlerden biri Örtüklenmemiş Sarılmış İsteğe Bağlı kullanmaktır, ancak daha iyi bir yol tembel bir değişken kullanmaktır:

class FileSystemItem {
}

class Directory : FileSystemItem {
    lazy var contents : [FileSystemItem] = {
        var loadedContents = [FileSystemItem]()
        // load contents and append to loadedContents
        return loadedContents
    }()
}

Şimdi, üye değişkeni contentsilk erişilene kadar başlatılmaz. Bu, başlangıç ​​değerini hesaplamadan önce sınıfa doğru duruma girme şansı verir.

Not: Bu, yukarıdaki # 1 ile çelişiyor gibi görünebilir. Ancak yapılması gereken önemli bir ayrım var. Özelliklere buttonOriginalWidtherişmeden önce düğmelerin genişliğini değiştirmeyi önlemek için viewDidLoad sırasında yukarıdakilerin ayarlanması gerekir.

2. Başka Her Yerde

Çoğunlukla, yanlışlıkla kullanılırsa, uygulamanıza erişilirken tüm uygulamanız kilitleneceğinden Örtülü Olarak Açılmamış Seçeneklerden kaçınılmalıdır nil. Bir değişkenin sıfır olup olmayacağından emin değilseniz, her zaman varsayılan bir İsteğe bağlı kullanmayı varsayılan olarak kullanın. nilKesinlikle olmayan bir değişkeni açmak kesinlikle çok fazla acıtmaz.


4
Bu yanıt beta 5 için güncellenmelidir if someOptional. Artık kullanamazsınız .
Noel Baba

2
@SantaClaus hasValueisteğe bağlı olarak tanımlanır. Ben semantik tercih hasValueolanların != nil. nilBaşka dillerde kullanmayan yeni programcılar için çok daha anlaşılır olduğunu düşünüyorum . hasValueçok daha mantıklı nil.
drewag

2
Görünüşe göre hasValuebeta 6'dan çekildi. Ash geri koydu ... github.com/AshFurrow/hasValue
Chris Wagner

1
@newacct Objc başlatıcılarının dönüş türü ile ilgili olarak, daha dolaylı olarak Örtük Olarak Açılmamış İsteğe Bağlı bir seçenektir. "İsteğe bağlı olmayan" kullanmak için tanımladığınız davranış, Örtük Olarak Açılmamış Bir İsteğe Bağlı'nın tam olarak yapacağı şeydir (erişilinceye kadar başarısız olmaz). Programın daha önce zorla açarak başarısız olmasına izin vermekle ilgili olarak, isteğe bağlı olmayan bir kullanımın tercih edildiğini kabul ediyorum, ancak bu her zaman mümkün değildir.
drewag

1
@confile no. Ne olursa olsun, Objective-C'de bir işaretçi olarak görünecektir (isteğe bağlı, örtük olarak sarılmış veya isteğe bağlı değilse).
drewag

56

Örtük olarak açılmamış opsiyoneller, bir özelliği gerçekten kapakların altında isteğe bağlı olması gerektiğinde isteğe bağlı olmayan olarak sunmak için kullanışlıdır. Bu genellikle, her biri diğerine referans gerektiren iki ilişkili nesne arasındaki "düğümü bağlamak" için gereklidir. Her iki referansın da aslında isteğe bağlı olmadığı zaman anlamlıdır , ancak çift başlatılırken bunlardan birinin sıfır olması gerekir.

Örneğin:

// These classes are buddies that never go anywhere without each other
class B {
    var name : String
    weak var myBuddyA : A!
    init(name : String) {
        self.name = name
    }
}

class A {
    var name : String
    var myBuddyB : B
    init(name : String) {
        self.name = name
        myBuddyB = B(name:"\(name)'s buddy B")
        myBuddyB.myBuddyA = self
    }
}

var a = A(name:"Big A")
println(a.myBuddyB.name)   // prints "Big A's buddy B"

Herhangi bir Börnek her zaman geçerli bir myBuddyAreferansa sahip olmalıdır , bu nedenle kullanıcının isteğe bağlı olarak davranmasını istemiyoruz, ancak başvurmak zorunda Bkalmadan önce bir inşa edebilmemiz için isteğe bağlı olması Agerekiyor.

ANCAK! Bu tür karşılıklı referans gereksinimi genellikle sıkı bağlantı ve zayıf tasarımın bir göstergesidir. Kendinizi örtük olarak açılmamış seçeneklere güveniyorsanız, muhtemelen çapraz bağımlılıkları ortadan kaldırmak için yeniden düzenleme yapmayı düşünmelisiniz.


7
Bence bu dil özelliğini yaratma nedenlerinden biri@IBOutlet
Jiaaro

11
"HOWEVER" uyarısı için +1. Her zaman doğru olmayabilir, ama kesinlikle dikkat edilmesi gereken bir şey.
JMD

4
Hala A ve B örtük arasında güçlü bir referans döngüsü isteğe bağlı öğeleri açılmamış olması YAPMAYIN zayıf referans oluşturmak. Hala myByddyA veya myBuddyB'yi zayıf olarak ilan etmeniz gerekiyor (muhtemelen myBuddyA)
drewag

6
Dolaylı olarak Kaydırılmamış Opsiyonlar bellek yönetimi ile hiçbir ilgisi vardır ve: bu cevap yanlış ve tehlikeli yanıltıcı neden daha da açık olmak gerekirse yok döngüleri korumak engeller. Bununla birlikte, Örtük Olarak Açılmamış Seçenekler, iki yönlü referansı ayarlamak için açıklanan durumda hala yararlıdır. Yani sadece weakbildirimi eklemek ve "güçlü bir tutma döngüsü oluşturmadan" kaldırmak
drewag

1
@drewag: Haklısın - Koruma döngüsünü kaldırmak için cevabı düzenledim. Arka referansı zayıflatmayı amaçladım ama sanırım aklımdan düştü.
n8gray

37

Örtülü olarak açılmamış seçenekler, mevcut kakao çerçeveleri ve sözleşmeleriyle birlikte çalışmak zorunda olan hibrit ortamda çalışmayı daha keyifli hale getirmek için pragmatik bir uzlaşmadır ve aynı zamanda Swift derleyici tarafından daha güvenli programlama paradigmasına kademeli olarak geçiş yapılmasına izin verir.

Swift kitabı, Temeller bölümünde, Örtük Olarak Açılmamış Seçenekler bölümünde şöyle yazıyor:

Örtük olarak kaydırılmamış opsiyoneller, isteğe bağlı ilk tanımlandıktan hemen sonra bir isteğe bağlı değerinin varlığını doğruladığında ve bundan sonraki her noktada kesinlikle var olduğu varsayıldığında faydalıdır. Swift'teki örtük olarak açılmamış seçeneklerin birincil kullanımı, Sahipsiz Referanslar ve Örtük Olarak Açılmamış İsteğe Bağlı Özellikler'de açıklandığı gibi sınıf başlatma sırasındadır .

Örtük olarak paketlenmemiş bir isteğe bağlı, isteğe bağlı olarak kullanıldığında otomatik olarak paketin açılmasına izin vermek olarak düşünebilirsiniz. Her kullandığınızda isteğe bağlı adından sonra bir ünlem işareti koymak yerine, bildirirken isteğe bağlı türünden sonra bir ünlem işareti koyarsınız.

Bu durumlarda kullanmak için gelir olmayan nil-lık özelliklerinin kullanım kuralı ile kurulur ve sınıf başlatma sırasında derleyici tarafından zorlanan edilemez. Örneğin, UIViewControllerNIB'lerden veya Storyboard'lardan başlatılan, burada başlatmanın ayrı aşamalara ayrıldığı, ancak viewDidLoad()sizden sonra özelliklerin genellikle var olduğunu varsayabilirsiniz. Aksi takdirde, derleyiciyi tatmin etmek için, zorunlu kod çözme , isteğe bağlı bağlama veya isteğe bağlı zincirlemeyi yalnızca kodun ana amacını gizlemek için kullanmanız gerekiyordu.

Swift kitabının üst kısmında Otomatik Referans Sayımı bölümü de belirtilmektedir :

Ancak, her iki özelliğin de her zaman bir değere sahip olması ve nilbaşlatma tamamlandıktan sonra hiçbir özelliğin hiçbir zaman olmaması gereken üçüncü bir senaryo vardır . Bu senaryoda, bir sınıfta sahipsiz bir özelliği diğer sınıfta örtük olarak kaydırılmamış isteğe bağlı bir özellik ile birleştirmek yararlıdır.

Bu, başlatma işlemi tamamlandıktan sonra her iki özelliğe de doğrudan erişilmesini sağlar (isteğe bağlı paket açmadan) ve yine de bir referans döngüsünden kaçınır.

Bu, çöp toplanmış bir dil olmama tuhaflıklarına düşmektedir, bu nedenle tutma döngülerinin kırılması bir programcı olarak üzerinizdedir ve örtük olarak açılmamış seçenekler, bu tuhaflığı gizlemek için bir araçtır.

Bu, “Kodunuzda örtük olarak açılmamış opsiyonelleri ne zaman kullanmalı?” soru. Bir uygulama geliştiricisi olarak, çoğunlukla, Objective-C ile yazılmış, isteğe bağlı türleri ifade etme yeteneğine sahip olmayan kütüphanelerin yöntem imzalarında karşılaşırsınız.

Gönderen Kakao ve Objective-C, bölüm ile Swift kullanma nil ile Çalışma :

Objective-C bir nesnenin sıfır olmadığını garanti etmediği için Swift, argüman türlerinde ve dönüş türlerindeki tüm sınıfları içe aktarılan Objective-C API'lerinde isteğe bağlı yapar. Bir Objective-C nesnesi kullanmadan önce, eksik olmadığından emin olmalısınız.

Bazı durumlarda, bir Objective-C yöntemi veya özelliğinin hiçbir zaman bir nesne başvurusu döndürmediğinden kesinlikle emin olabilirsiniz nil. Bu özel senaryodaki nesnelerle çalışmayı daha kolay hale getirmek için Swift, nesne türlerini örtük olarak açılmamış isteğe bağlı öğeler olarak içe aktarır . Örtük olarak paketlenmemiş isteğe bağlı türler, isteğe bağlı türlerin tüm güvenlik özelliklerini içerir. Ayrıca, değeri kontrol etmeden doğrudan erişebilirsiniz.nilveya kendiniz açabilirsiniz. Bu tür isteğe bağlı türdeki değere önce güvenli bir şekilde paketini açmadan eriştiğinizde, örtük olarak paketlenmemiş isteğe bağlı değerin eksik olup olmadığını kontrol eder. Değer eksikse, bir çalışma zamanı hatası oluşur. Sonuç olarak, değerin eksik olamayacağından emin olmadığınız sürece, örtülü olarak açılmamış bir isteğe bağlı olanı her zaman kontrol etmeli ve paketini açmalısınız.

... ve ötesi burada yatıyordu ejderha


Bu kapsamlı cevap için teşekkürler. Örtülü Olarak Paketlenmemiş Seçeneklerin ne zaman kullanılacağı ve standart bir değişkenin ne zaman yeterli olacağı konusunda hızlı bir kontrol listesi düşünebilir misiniz?
Hairgami_Master

@Hairgami_Master Kendi cevabımı bir liste ve somut örneklerle
ekledim

18

Tek satırlı (veya birkaç satırlı) basit örnekler, seçeneklerin davranışını çok iyi kapsamaz - evet, bir değişken bildirir ve hemen bir değer sağlarsanız, isteğe bağlı bir nokta yoktur.

Şimdiye kadar gördüğüm en iyi durum, nesne başlatıldıktan sonra gerçekleşen kurulum ve ardından bu kurulumu takip etmek için "garanti edilen" kullanımdır, örneğin bir görünüm denetleyicisinde:

class MyViewController: UIViewController {

    var screenSize: CGSize?

    override func viewDidLoad {
        super.viewDidLoad()
        screenSize = view.frame.size
    }

    @IBAction printSize(sender: UIButton) {
        println("Screen size: \(screenSize!)")
    }
}

printSizeGörünüm yüklendikten sonra çağrılacağını biliyoruz - bu görünümün içindeki bir kontrole bağlanan bir eylem yöntemidir ve başka türlü çağırmamaya özen gösterdik. Böylece kendimizi ile bazı isteğe bağlı kontrol / bağlama kaydedebilirsiniz !. Swift bu garantiyi tanıyamaz (en azından Apple durma problemini çözene kadar), bu yüzden derleyiciye var olduğunu söylersiniz.

Ancak bu, tip güvenliği bir dereceye kadar kırmaktadır. Örtük olarak açılmamış isteğe bağlı bir seçeneğiniz olan Anyplace, "garantiniz" her zaman tutmazsa uygulamanızın çökebileceği bir yerdir, bu yüzden az kullanmanız gereken bir özelliktir. Ayrıca, !her zaman kullanmak bağırıyormuş gibi ses çıkarır ve kimse bundan hoşlanmaz.


Neden sadece screenSize öğesini CGSize olarak (yükseklik: 0, genişlik: 0) başlatmıyor ve değişkene her eriştiğinizde bağırmak zorunda kalmıyorsunuz?
Martin Gordon

Bir boyut en iyi örnek olmayabilir, çünkü CGSizeZerogerçek dünya kullanımında iyi bir sentinel değeri olabilir. Peki ya uçtan yüklenmiş bir boyutunuz varsa, bu aslında sıfır olabilir mi? Sonra CGSizeZerobir sentinel olarak kullanmak , ayarlanmamış ve sıfıra ayarlanmış bir değeri ayırt etmenize yardımcı olmaz. Dahası, bu init, uçtan (veya daha sonra başka bir yerden ) yüklenen diğer tipler için de aynı derecede geçerlidir : dizeler, alt görünümlere referanslar, vb.
rickster

2
Fonksiyonel dillerde Opsiyonel noktasının bir kısmı sentinel değerlerine sahip olmamalıdır. Ya bir değerin var ya da yok. Eksik bir değeri gösteren bir değere sahip olduğunuz bir vakanız olmamalıdır.
Wayne Tanner

4
Bence OP'nin sorusunu yanlış anladın. OP, seçeneklerle ilgili genel durum hakkında değil, özellikle örtük olarak kaydırılmamış seçeneklerin gereksinimi / kullanımı hakkında sorular sormaz ( let foo? = 42daha doğrusu değil let foo! = 42). Bu bunu ele almıyor. (Bu seçeneklerle ilgili bir cevap olabilir, dikkat edin, ancak farklı / ilgili bir hayvan olan örtük olarak kaydırılmamış seçeneklerle ilgili olmayabilir.)
JMD

15

Apple, Hızlı Programlama Dili -> Otomatik Referans Sayımı -> Sınıf Örnekleri Arasında Güçlü Referans Döngülerini Çözme -> Sahipsiz Referanslar ve Örtülü Olarak Sarılmış İsteğe Bağlı Özellikler'de harika bir örnek veriyor

class Country {
    let name: String
    var capitalCity: City! // Apple finally correct this line until 2.0 Prerelease (let -> var)
    init(name: String, capitalName: String) {
        self.name = name
        self.capitalCity = City(name: capitalName, country: self)
    }
}

class City {
    let name: String
    unowned let country: Country
    init(name: String, country: Country) {
        self.name = name
        self.country = country
    }
}

İçin başlatıcı, için başlatıcıdan Cityçağrılır Country. Ancak, için başlatıcı Countrygeçemez selfiçin Cityyeni kadar başlatıcısı Countrytarif edildiği gibi, örneğin tam olarak başlatılır İki Fazlı Başlatma .

Bu gereksinimle başa çıkmak için, capitalCityözelliğini Countryörtük olarak açılmamış isteğe bağlı bir özellik olarak bildirirsiniz.


Bu cevapta bahsedilen öğretici burada .
Franklin Yu

3

Örtük seçeneklerin mantığını ilk önce zorla açmanın gerekçesine bakarak açıklamak daha kolaydır.

Kullanarak isteğe bağlı (örtülü veya örtük) zorla açılmayı! operatörünüz, kodunuzun hiç hata olmadığından ve isteğe bağlı öğenin, paketin kaldırıldığı yerde zaten bir değere sahip olduğundan eminseniz anlamına gelir. Olmadan! işleci, muhtemelen isteğe bağlı bir bağlama ile iddia edersiniz:

 if let value = optionalWhichTotallyHasAValue {
     println("\(value)")
 } else {
     assert(false)
 }

ki bu kadar hoş değil

println("\(value!)")

Şimdi, örtük seçenek seçenekleri , tüm olası akışlarda, açılmadan her zaman bir değere sahip olmasını beklediğiniz bir isteğe bağlı olduğunu ifade etmenizi sağlar . Yani sadece size yardımcı olmada bir adım daha ileri gidiyor - yazma zorunluluğunu gevşeterek! her seferinde açmak ve akışla ilgili varsayımlarınızın yanlış olması durumunda çalışma zamanının hala hata vermesini sağlamak.


1
@newacct: kodunuz aracılığıyla tüm olası akışlarda sıfır olmayan, üst öğe (sınıf / yapı) başlatmadan ayırma yoluyla sıfır olmayan ile aynı değildir. Arayüz Oluşturucu klasik örnektir (ancak birçok gecikmeli başlatma paterni vardır): bir sınıf yalnızca bir uçtan hiç kullanıldıysa, çıkış değişkenleri ayarlanmaz init(hatta uygulayamayabilirsiniz), ancak ' yeniden garanti sonra yapılır awakeFromNib/ ' viewDidLoad.
rickster

3

Eminseniznil , örtük olarak açılmamış isteğe bağlıler yerine isteğe bağlı bir değer döndürürse, bu değerleri isteğe bağlı olarak doğrudan yakalamak için kullanılır ve isteğe bağlı olmayanlar bunu yapamaz.

//Optional string with a value
let optionalString: String? = "This is an optional String"

//Declaration of an Implicitly Unwrapped Optional String
let implicitlyUnwrappedOptionalString: String!

//Declaration of a non Optional String
let nonOptionalString: String

//Here you can catch the value of an optional
implicitlyUnwrappedOptionalString = optionalString

//Here you can't catch the value of an optional and this will cause an error
nonOptionalString = optionalString

Yani bu kullanım arasındaki fark

let someString : String! ve let someString : String


1
Bu OP'nin sorusuna cevap vermiyor. OP , Örtülü Olarak Açılmamış İsteğe Bağlı Birimin ne olduğunu bilir .
Franklin Yu

0

Bence Optionalbu yeni başlayanlar için kafa karıştırıcı olan bu yapı için kötü bir isim.

Diğer diller (örneğin Kotlin ve C #) terimi kullanır Nullableve bunu anlamayı çok daha kolay hale getirir.

Nullablebu türde bir değişkene null değer atayabileceğiniz anlamına gelir. Eğer öyleyse, ona Nullable<SomeClassType>null atayabilirsiniz, eğer öyleyse SomeClassType, yapamazsınız. Swift böyle çalışır.

Neden kullanıyorsunuz? Bazen boş değerlere sahip olmanız gerekir, bu yüzden. Örneğin, bir sınıfta bir alana sahip olmak istediğinizi bildiğinizde, ancak o sınıfın bir örneğini oluştururken bunu hiçbir şeye atayamazsınız, ancak daha sonra devam edersiniz. Örnek vermeyeceğim, çünkü insanlar onları burada zaten sağladı. Bunu sadece 2 sent vermek için yazıyorum.

Btw, bunun Kotlin ve C # gibi diğer dillerde nasıl çalıştığına bakmanızı öneririm.

Kotlin'deki bu özelliği açıklayan bir bağlantı: https://kotlinlang.org/docs/reference/null-safety.html

Java ve Scala gibi diğer diller Optionals'ye sahiptir, ancak OptionalSwift'teki s'den farklı çalışırlar , çünkü Java ve Scala tipleri varsayılan olarak geçersizdir.

Sonuçta, bu özelliğin adlandırılmış olması gerektiğini düşünüyorum Nullable Swift'teOptional ...


0

Implicitly Unwrapped OptionalOptionalbir programcı bir değişkeni açmaya zorlamadığı için sözdizimsel bir şekerdir . Sırasında başlatılamayan two-phase initialization processve sıfır olmayan anlamına gelen bir değişken için kullanılabilir . Bu değişken kendini sıfır olmayan gibi davranır , ancak aslında isteğe bağlı bir değişkendir. İyi bir örnek - Interface Builder'ın satış noktaları

Optional genellikle tercih edilir

var nonNil: String = ""
var optional: String?
var implicitlyUnwrappedOptional: String!

func foo() {
    //get a value
    nonNil.count
    optional?.count

    //Danderour - makes a force unwrapping which can throw a runtime error
    implicitlyUnwrappedOptional.count

    //assign to nil
//        nonNil = nil //Compile error - 'nil' cannot be assigned to type 'String'
    optional = nil
    implicitlyUnwrappedOptional = nil
}
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.