Apa nilai opsional di Swift?

267

Dari dokumentasi Apple :

Anda bisa menggunakan ifdan letbersama - sama bekerja dengan nilai-nilai yang mungkin hilang. Nilai-nilai ini direpresentasikan sebagai opsional. Nilai opsional mengandung nilai atau berisi niluntuk menunjukkan bahwa nilai tersebut hilang. Tulis tanda tanya ( ?) setelah jenis nilai untuk menandai nilai sebagai opsional.

Mengapa Anda ingin menggunakan nilai opsional?

Tim Vermeulen
sumber
1
Opsional juga dapat dilihat sebagai implementasi dari Opsi / Mungkin monad . Blog ini di sini melakukan pekerjaan yang baik untuk mencoba menjelaskan apa yang sebaliknya merupakan konsep yang sulit.
StuartLC
tldr: "Swift perlu Anda jelaskan kapan nilai bisa hilang dan kapan dijamin ada." dari jawaban
jonatan

Jawaban:

532

Opsional dalam Swift adalah jenis yang dapat menyimpan nilai atau tidak ada nilai. Opsional ditulis dengan menambahkan a ?ke jenis apa pun:

var name: String? = "Bertie"

Opsional (bersama dengan Generik) adalah salah satu konsep Swift yang paling sulit untuk dipahami. Karena cara mereka ditulis dan digunakan, mudah untuk mendapatkan ide yang salah tentang apa mereka. Bandingkan opsi di atas untuk membuat String normal:

var name: String = "Bertie" // No "?" after String

Dari sintaks sepertinya String opsional sangat mirip dengan String biasa. Ini bukan. String opsional bukan String dengan beberapa pengaturan "opsional" dihidupkan. Ini bukan jenis spesial String. String dan String opsional adalah tipe yang sama sekali berbeda.

Inilah hal yang paling penting untuk diketahui: Pilihan adalah sejenis wadah. String opsional adalah wadah yang mungkin berisi String. Int opsional adalah wadah yang mungkin mengandung Int. Pikirkan opsional sebagai semacam paket. Sebelum Anda membukanya (atau "membuka" dalam bahasa opsional) Anda tidak akan tahu apakah itu mengandung sesuatu atau tidak sama sekali.

Anda dapat melihat bagaimana opsional diterapkan di Perpustakaan Standar Swift dengan mengetikkan "Opsional" ke dalam file Swift apa pun dan mengkliknya. Inilah bagian penting dari definisi:

enum Optional<Wrapped> {
    case none
    case some(Wrapped)
}

Opsional hanya merupakan enumsalah satu dari dua kasus: .noneatau .some. Jika itu .some, ada nilai terkait yang, dalam contoh di atas, akan menjadi String"Halo". Pilihan menggunakan Generics untuk memberikan tipe ke nilai terkait. Jenis String opsional tidak String, itu Optional, atau lebih tepatnya Optional<String>.

Segala sesuatu yang dilakukan Swift dengan opsional adalah keajaiban untuk membuat membaca dan menulis kode lebih lancar. Sayangnya ini mengaburkan cara kerjanya. Saya akan membahas beberapa trik nanti.

Catatan: Saya akan banyak berbicara tentang variabel opsional, tetapi tidak masalah untuk membuat konstanta opsional juga. Saya menandai semua variabel dengan tipe mereka untuk membuatnya lebih mudah untuk memahami tipe tipe yang sedang dibuat, tetapi Anda tidak harus dalam kode Anda sendiri.


Cara membuat opsional

Untuk membuat opsional, tambahkan ?setelah jenis yang ingin Anda bungkus. Jenis apa pun bisa opsional, bahkan jenis kustom Anda sendiri. Anda tidak dapat memiliki ruang antara jenis dan ?.

var name: String? = "Bob" // Create an optional String that contains "Bob"
var peter: Person? = Person() // An optional "Person" (custom type)

// A class with a String and an optional String property
class Car {
var modelName: String // must exist
var internalName: String? // may or may not exist
}

Menggunakan opsional

Anda dapat membandingkan opsi niluntuk melihat apakah ada nilai:

var name: String? = "Bob"
name = nil // Set name to nil, the absence of a value
if name != nil {
    print("There is a name")
}
if name == nil { // Could also use an "else"
    print("Name has no value")
}

Ini agak membingungkan. Ini menyiratkan bahwa opsional adalah satu atau lain hal. Entah nol atau "Bob". Ini tidak benar, opsional tidak berubah menjadi sesuatu yang lain. Membandingkannya dengan nol adalah trik untuk membuat kode yang lebih mudah dibaca. Jika opsional sama dengan nihil, ini berarti enum saat ini disetel ke .none.


Hanya opsional yang boleh nol

Jika Anda mencoba mengatur variabel non-opsional menjadi nil, Anda akan mendapatkan kesalahan.

var red: String = "Red"
red = nil // error: nil cannot be assigned to type 'String'

Cara lain untuk melihat opsional adalah sebagai pelengkap variabel Swift normal. Mereka adalah counterpart ke variabel yang dijamin memiliki nilai. Swift adalah bahasa yang hati-hati yang membenci ambiguitas. Sebagian besar variabel didefinisikan sebagai non-opsional, tetapi kadang-kadang ini tidak mungkin. Misalnya, bayangkan pengontrol tampilan yang memuat gambar baik dari cache atau dari jaringan. Mungkin atau mungkin tidak memiliki gambar itu pada saat pengontrol tampilan dibuat. Tidak ada cara untuk menjamin nilai untuk variabel gambar. Dalam hal ini Anda harus membuatnya opsional. Dimulai saat nildan ketika gambar diambil, opsional mendapatkan nilai.

Menggunakan opsional mengungkapkan niat pemrogram. Dibandingkan dengan Objective-C, di mana objek apa pun bisa nihil, Swift perlu Anda jelaskan kapan nilai bisa hilang dan kapan dijamin ada.


Untuk menggunakan opsional, Anda "membuka"

Opsional Stringtidak dapat digunakan sebagai pengganti yang sebenarnya String. Untuk menggunakan nilai terbungkus di dalam opsional, Anda harus membukanya. Cara termudah untuk membuka bungkusan opsional adalah dengan menambahkan !setelah nama opsional. Ini disebut "force unrapping". Ini mengembalikan nilai di dalam opsional (sebagai tipe asli) tetapi jika opsional nil, itu menyebabkan crash runtime. Sebelum membuka bungkus, Anda harus yakin ada nilainya.

var name: String? = "Bob"
let unwrappedName: String = name!
print("Unwrapped name: \(unwrappedName)")

name = nil
let nilName: String = name! // Runtime crash. Unexpected nil.

Memeriksa dan menggunakan opsional

Karena Anda harus selalu memeriksa nol sebelum membuka dan menggunakan opsional, ini adalah pola umum:

var mealPreference: String? = "Vegetarian"
if mealPreference != nil {
    let unwrappedMealPreference: String = mealPreference!
    print("Meal: \(unwrappedMealPreference)") // or do something useful
}

Dalam pola ini Anda memeriksa bahwa ada nilai, maka ketika Anda yakin itu, Anda memaksa membuka itu menjadi konstanta sementara untuk digunakan. Karena ini adalah hal yang biasa dilakukan, Swift menawarkan jalan pintas menggunakan "jika dibiarkan". Ini disebut "penjilidan opsional".

var mealPreference: String? = "Vegetarian"
if let unwrappedMealPreference: String = mealPreference {
    print("Meal: \(unwrappedMealPreference)") 
}

Ini menciptakan konstanta sementara (atau variabel jika Anda ganti letdengan var) yang cakupannya hanya di dalam kurung if. Karena harus menggunakan nama seperti "unwrappedMealPreference" atau "realMealPreference" adalah beban, Swift memungkinkan Anda untuk menggunakan kembali nama variabel asli, membuat nama temporer dalam lingkup braket

var mealPreference: String? = "Vegetarian"
if let mealPreference: String = mealPreference {
    print("Meal: \(mealPreference)") // separate from the other mealPreference
}

Berikut beberapa kode untuk menunjukkan bahwa variabel yang berbeda digunakan:

var mealPreference: String? = "Vegetarian"
if var mealPreference: String = mealPreference {
    print("Meal: \(mealPreference)") // mealPreference is a String, not a String?
    mealPreference = "Beef" // No effect on original
}
// This is the original mealPreference
print("Meal: \(mealPreference)") // Prints "Meal: Optional("Vegetarian")"

Ikatan opsional berfungsi dengan memeriksa untuk melihat apakah opsional sama dengan nol. Jika tidak, ia membuka opsi ke konstanta yang disediakan dan mengeksekusi blok. Dalam Xcode 8.3 dan yang lebih baru (Swift 3.1), mencoba untuk mencetak opsional seperti ini akan menyebabkan peringatan yang tidak berguna. Gunakan opsional debugDescriptionuntuk membungkamnya:

print("\(mealPreference.debugDescription)")

Apa itu opsional?

Opsional memiliki dua kasus penggunaan:

  1. Hal-hal yang dapat gagal (saya mengharapkan sesuatu tetapi saya tidak mendapatkan apa-apa)
  2. Hal-hal yang bukan apa-apa sekarang tetapi mungkin sesuatu nanti (dan sebaliknya)

Beberapa contoh nyata:

  • Properti yang bisa ada di sana atau tidak di sana, suka middleNameatau spousedi Personkelas
  • Metode yang dapat mengembalikan nilai atau tidak sama sekali, seperti mencari kecocokan dalam array
  • Metode yang dapat mengembalikan hasil atau mendapatkan kesalahan dan tidak menghasilkan apa-apa, seperti mencoba membaca konten file (yang biasanya mengembalikan data file) tetapi file tersebut tidak ada
  • Mendelegasikan properti, yang tidak selalu harus ditetapkan dan umumnya ditetapkan setelah inisialisasi
  • Untuk weakproperti di kelas. Hal yang mereka tunjuk dapat diatur nilkapan saja
  • Sumber daya besar yang mungkin harus dilepaskan untuk mendapatkan kembali memori
  • Saat Anda membutuhkan cara untuk mengetahui kapan suatu nilai telah ditetapkan (data belum dimuat> data) alih-alih menggunakan data yang terpisahDiisi Boolean

Opsional tidak ada di Objective-C tetapi ada konsep yang setara, mengembalikan nol. Metode yang dapat mengembalikan objek dapat mengembalikan nol. Ini berarti "tidak adanya objek yang valid" dan sering digunakan untuk mengatakan bahwa ada sesuatu yang salah. Ini hanya bekerja dengan objek Objective-C, bukan dengan primitif atau tipe-C dasar (enum, struct). Objective-C sering memiliki tipe khusus untuk mewakili tidak adanya nilai-nilai ini ( NSNotFoundyang sebenarnya NSIntegerMax, kCLLocationCoordinate2DInvaliduntuk mewakili koordinat yang tidak valid, -1atau beberapa nilai negatif juga digunakan). Coder harus mengetahui nilai-nilai khusus ini sehingga harus didokumentasikan dan dipelajari untuk setiap kasus. Jika suatu metode tidak dapat mengambil nilsebagai parameter, ini harus didokumentasikan. Di Objective-C,niladalah pointer sama seperti semua objek didefinisikan sebagai pointer, tetapi nilmenunjuk ke alamat (nol) tertentu. Dalam bahasa Swift, niladalah literal yang berarti tidak adanya tipe tertentu.


Dibandingkan dengan nil

Anda dulu dapat menggunakan opsi apa pun sebagai Boolean:

let leatherTrim: CarExtras? = nil
if leatherTrim {
    price = price + 1000
}

Dalam versi terbaru Swift yang harus Anda gunakan leatherTrim != nil. Kenapa ini? Masalahnya adalah bahwa Booleandapat dibungkus dengan opsional. Jika sudah Booleanseperti ini:

var ambiguous: Boolean? = false

ia memiliki dua jenis "salah", satu di mana tidak ada nilai dan satu di mana ia memiliki nilai tetapi nilainya false. Swift membenci ambiguitas jadi sekarang Anda harus selalu memeriksa opsi menentang nil.

Anda mungkin bertanya-tanya apa gunanya opsional Boolean? Seperti dengan opsional lainnya .nonenegara dapat menunjukkan bahwa nilainya belum diketahui. Mungkin ada sesuatu di ujung lain dari panggilan jaringan yang membutuhkan waktu untuk polling. Boolean Opsional juga disebut " Boolean Tiga Nilai "


Trik cepat

Swift menggunakan beberapa trik untuk memungkinkan opsional berfungsi. Pertimbangkan tiga baris kode opsional yang tampak biasa ini;

var religiousAffiliation: String? = "Rastafarian"
religiousAffiliation = nil
if religiousAffiliation != nil { ... }

Tak satu pun dari baris ini harus dikompilasi.

  • Baris pertama menetapkan String opsional menggunakan String literal, dua jenis berbeda. Kalaupun ini adalah Stringtipe yang berbeda
  • Baris kedua menetapkan String opsional menjadi nihil, dua jenis berbeda
  • Baris ketiga membandingkan string opsional dengan nol, dua tipe berbeda

Saya akan membahas beberapa detail implementasi opsional yang memungkinkan baris ini bekerja.


Membuat opsional

Menggunakan ?untuk membuat opsional adalah gula sintaksis, diaktifkan oleh kompiler Swift. Jika Anda ingin melakukannya jauh, Anda dapat membuat opsional seperti ini:

var name: Optional<String> = Optional("Bob")

OptionalInisialisasi pertama panggilan ini public init(_ some: Wrapped), yang menyimpulkan jenis yang terkait opsional dari jenis yang digunakan dalam tanda kurung.

Cara lebih lama untuk membuat dan mengatur opsional:

var serialNumber:String? = Optional.none
serialNumber = Optional.some("1234")
print("\(serialNumber.debugDescription)")

Pengaturan opsional untuk nil

Anda dapat membuat opsional tanpa nilai awal, atau membuatnya dengan nilai awal nil(keduanya memiliki hasil yang sama).

var name: String?
var name: String? = nil

Mengizinkan opsional sama nildengan diaktifkan oleh protokol ExpressibleByNilLiteral(sebelumnya bernama NilLiteralConvertible). Opsional dibuat dengan Optionalpenginisialisasi kedua public init(nilLiteral: ()),. Dokumen mengatakan bahwa Anda tidak boleh menggunakan ExpressibleByNilLiteralapa pun kecuali opsional, karena itu akan mengubah arti nihil dalam kode Anda, tetapi dimungkinkan untuk melakukannya:

class Clint: ExpressibleByNilLiteral {
    var name: String?
    required init(nilLiteral: ()) {
        name = "The Man with No Name"
    }
}

let clint: Clint = nil // Would normally give an error
print("\(clint.name)")

Protokol yang sama memungkinkan Anda untuk mengatur opsional yang sudah dibuat nil. Meskipun tidak disarankan, Anda dapat menggunakan penginisialisasi literal nil secara langsung:

var name: Optional<String> = Optional(nilLiteral: ())

Membandingkan opsional untuk nil

Opsional menentukan dua operator "==" dan "! =" Khusus, yang dapat Anda lihat dalam Optionaldefinisi. Yang pertama ==memungkinkan Anda untuk memeriksa apakah ada opsi yang sama dengan nol. Dua opsional berbeda yang disetel ke .tidak akan selalu sama jika jenis terkait adalah sama. Ketika Anda membandingkan dengan nol, di belakang layar Swift membuat opsional dari jenis terkait yang sama, diatur ke. Tidak ada yang kemudian menggunakannya untuk perbandingan.

// How Swift actually compares to nil
var tuxedoRequired: String? = nil
let temp: Optional<String> = Optional.none
if tuxedoRequired == temp { // equivalent to if tuxedoRequired == nil
    print("tuxedoRequired is nil")
}

==Operator kedua memungkinkan Anda untuk membandingkan dua opsional. Keduanya harus tipe yang sama dan tipe tersebut harus sesuai Equatable(protokol yang memungkinkan membandingkan hal-hal dengan operator "==" reguler). Swift (mungkin) membuka dua nilai dan membandingkannya secara langsung. Ini juga menangani case di mana satu atau kedua opsional berada .none. Perhatikan perbedaan antara membandingkan dengan nilliteral.

Selain itu, ini memungkinkan Anda untuk membandingkan Equatablejenis apa pun dengan pembungkus opsional jenis itu:

let numberToFind: Int = 23
let numberFromString: Int? = Int("23") // Optional(23)
if numberToFind == numberFromString {
    print("It's a match!") // Prints "It's a match!"
}

Di belakang layar, Swift membungkus non-opsional sebagai opsional sebelum perbandingan. Ia bekerja dengan literal juga ( if 23 == numberFromString {)

Saya mengatakan ada dua ==operator, tetapi sebenarnya ada sepertiga yang memungkinkan Anda untuk menempatkan nildi sisi kiri perbandingan

if nil == name { ... }

Memilih Penamaan

Tidak ada konvensi Swift untuk penamaan tipe opsional berbeda dari tipe non-opsional. Orang menghindari menambahkan sesuatu ke nama untuk menunjukkan bahwa itu adalah opsional (seperti "opsionalMiddleName", atau "possibleNumberAsString") dan biarkan deklarasi menunjukkan bahwa itu adalah tipe opsional. Ini menjadi sulit ketika Anda ingin memberi nama sesuatu untuk menyimpan nilai dari opsional. Nama "middleName" menyiratkan bahwa itu adalah tipe String, jadi ketika Anda mengekstrak nilai String dari itu, Anda sering dapat berakhir dengan nama-nama seperti "actualMiddleName" atau "unwrappedMiddleName" atau "realMiddleName". Gunakan penjilidan opsional dan gunakan kembali nama variabel untuk menyiasatinya.


Definisi resmi

Dari "The Basics" dalam Bahasa Pemrograman Swift :

Swift juga memperkenalkan tipe opsional, yang menangani ketiadaan nilai. Opsional mengatakan "ada nilai, dan sama dengan x" atau "tidak ada nilai sama sekali". Opsional mirip dengan menggunakan nil dengan pointer di Objective-C, tetapi mereka bekerja untuk semua jenis, bukan hanya kelas. Opsional lebih aman dan lebih ekspresif daripada petunjuk nol di Objective-C dan merupakan jantung dari banyak fitur Swift yang paling kuat.

Opsional adalah contoh dari fakta bahwa Swift adalah jenis bahasa yang aman. Swift membantu Anda memperjelas jenis nilai yang dapat digunakan oleh kode Anda. Jika bagian dari kode Anda mengharapkan sebuah String, ketik safety mencegah Anda melewatkannya dengan Int. Ini memungkinkan Anda untuk menangkap dan memperbaiki kesalahan sedini mungkin dalam proses pengembangan.


Untuk menyelesaikannya, inilah puisi dari tahun 1899 tentang opsional:

Kemarin di tangga
saya bertemu dengan seorang pria yang tidak ada di sana.
Dia tidak ada di sana lagi hari ini
saya berharap, saya berharap dia akan pergi

Antigonish


Sumber lainnya:

raja nevan
sumber
5
@ Kanaanedeoglu Sayangnya Steve sangat opsional. Dia ada di sini dan sekarang tidak.
raja nevan
19
if myStringtidak lagi dikompilasi. Kamu butuh if myString != nil. Lihat dokumentasi .
Pang
5
Penjelasan terbaik dan paling jelas untuk? dan! gunakan di Swift yang saya temukan di web. terima kasih
mindbomb
2
mateo menjelaskan secara mendalam Opsional, menjangkau dalam Kedalaman dan contoh mudah.
iluvatar_GR
4
Terima kasih atas penjelasan ini, jauh lebih jelas daripada dokumentasi Apple sendiri.
yesthisisjoe
16

Mari kita ambil contoh NSError, jika tidak ada kesalahan yang dikembalikan Anda ingin menjadikannya opsional untuk mengembalikan nol. Tidak ada gunanya memberikan nilai padanya jika tidak ada kesalahan ..

var error: NSError? = nil

Ini juga memungkinkan Anda untuk memiliki nilai default. Jadi, Anda dapat menetapkan metode nilai default jika fungsi tidak lulus apa pun

func doesntEnterNumber(x: Int? = 5) -> Bool {
    if (x == 5){
        return true
    } else {
        return false
    }
}
John Riselvato
sumber
Kalimat "Jika nihil, hasil dari ekspresi apa pun dengan nihil juga" adalah salah. func isNil<T>(t: T?) -> Bool { return t == nil }akan kembali truebahkan jika ada nilai opsional yang ada nildalam ekspresi.
mengembalikan true
Contoh kode yang sangat buruk. Tidak bisakah kamu memikirkan sesuatu yang lebih baik? Kenapa tidak sederhana saja return x == 5? Apa yang istimewa dari 5?
Atomosk
Tidak, 2 tahun yang lalu saya tidak bisa memikirkan sesuatu yang lebih baik. Hari ini ya, tetapi apakah ini bisa dipahami? Iya. Terima kasih atas input @Atomosk, ini sangat membantu.
John Riselvato
12

Anda tidak dapat memiliki variabel yang mengarah ke nilSwift - tidak ada pointer, dan tidak ada pointer nol. Namun dalam API, Anda sering ingin dapat menunjukkan jenis nilai tertentu, atau kurangnya nilai - misalnya apakah jendela saya memiliki delegasi, dan jika ya, siapa itu? Opsional adalah jenis Swift yang aman dan aman untuk melakukan hal ini.

rickster
sumber
11

Saya membuat jawaban singkat, yang meringkas sebagian besar di atas, untuk membersihkan ketidakpastian yang ada di kepala saya sebagai pemula:

Diseberang ke Objective-C, tidak ada variabel yang dapat mengandung nil di Swift, jadi tipe variabel opsional ditambahkan (variabel yang didekenisasi oleh "?"):

    var aString = nil //error

Perbedaan besar adalah bahwa variabel opsional tidak secara langsung menyimpan nilai (seperti variabel Obj-C normal) mereka mengandung dua status : " memiliki nilai " atau " memiliki nihil ":

    var aString: String? = "Hello, World!"
    aString = nil //correct, now it contains the state "has nil"

Oleh karena itu, Anda dapat memeriksa variabel-variabel tersebut dalam situasi yang berbeda:

if let myString = aString? {
     println(myString)
}
else { 
     println("It's nil") // this will print in our case
}

Dengan menggunakan "!" akhiran, Anda juga dapat mengakses nilai yang dibungkus di dalamnya, hanya jika ada . (Yaitu tidak nol ):

let aString: String? = "Hello, World!"
// var anotherString: String = aString //error
var anotherString: String = aString!

println(anotherString) //it will print "Hello, World!"

Itu sebabnya Anda perlu menggunakan "?" dan "!" dan tidak menggunakan semuanya secara default. (Ini adalah kebingungan terbesar saya)

Saya juga setuju dengan jawaban di atas: Jenis opsional tidak dapat digunakan sebagai boolean .

Teodor Ciuraru
sumber
7

Dalam variabel C objektif tanpa nilai sama dengan 'nil' (juga dimungkinkan untuk menggunakan nilai 'nil' sama dengan 0 dan salah), maka dimungkinkan untuk menggunakan variabel dalam pernyataan bersyarat (Variabel yang memiliki nilai sama dengan 'BENAR' 'dan mereka yang tidak memiliki nilai sama dengan' SALAH ').

Swift memberikan keamanan jenis dengan memberikan 'nilai opsional'. yaitu mencegah kesalahan yang terbentuk dari menetapkan variabel dari jenis yang berbeda.

Jadi di Swift, hanya boolean yang dapat diberikan pada pernyataan bersyarat.

var hw = "Hello World"

Di sini, meskipun 'hw' adalah string, itu tidak dapat digunakan dalam pernyataan if seperti dalam objektif C.

//This is an error

if hw

 {..}

Untuk itu perlu dibuat sebagai,

var nhw : String? = "Hello World"

//This is correct

if nhw

 {..}
Gokul
sumber
5

Nilai opsional memungkinkan Anda menunjukkan tidak adanya nilai. Sedikit seperti NULL di SQL atau NSNull di Objective-C. Saya kira ini akan menjadi peningkatan karena Anda dapat menggunakan ini bahkan untuk tipe "primitif".

// Reimplement the Swift standard library's optional type
enum OptionalValue<T> {
    case None
    case Some(T)
}
var possibleInteger: OptionalValue<Int> = .None
possibleInteger = .Some(100)

Kutipan dari: Apple Inc. “Bahasa Pemrograman Swift.” iBooks. https://itun.es/gb/jEUH0.l

Maria Zverina
sumber
6
nilhanyalah gula sintaksis untuk konstanta enum OptionalValue<T>.None(di mana Tjenis yang sesuai dengan konteks tempat Anda menggunakan nil) ?adalah jalan pintas untuk OptionalValue<T>.Some(T).
rickster
4

Pilihan berarti bahwa Swift tidak sepenuhnya yakin apakah nilainya sesuai dengan tipe: misalnya, Int? berarti Swift tidak sepenuhnya yakin apakah angka itu adalah Int.

Untuk menghapusnya, ada tiga metode yang bisa Anda terapkan.

1) Jika Anda benar-benar yakin dengan jenisnya, Anda dapat menggunakan tanda seru untuk memaksa membuka bungkusnya, seperti ini:

// Here is an optional variable:

var age: Int?

// Here is how you would force unwrap it:

var unwrappedAge = age!

Jika Anda memaksanya membuka bungkusan opsional dan sama dengan nihil, Anda mungkin mengalami kesalahan kerusakan ini:

masukkan deskripsi gambar di sini

Ini belum tentu aman, jadi inilah metode yang mungkin mencegah crash jika Anda tidak yakin dengan jenis dan nilai:

Metode 2 dan tiga perlindungan terhadap masalah ini.

2) Pilihan Tersirat yang Tidak Dibungkus

 if let unwrappedAge = age {

 // continue in here

 }

Perhatikan bahwa tipe yang tidak terbuka sekarang adalah Int , bukan Int? .

3) Pernyataan penjaga

 guard let unwrappedAge = age else { 
   // continue in here
 }

Dari sini, Anda dapat melanjutkan dan menggunakan variabel yang tidak terbuka. Pastikan hanya untuk memaksa membuka (dengan!), Jika Anda yakin dengan jenis variabel.

Semoga berhasil dengan proyek Anda!

GJZ
sumber
1

Ketika saya mulai belajar Swift, sangat sulit untuk menyadari mengapa opsional .

Mari kita berpikir dengan cara ini. Mari pertimbangkan kelas Personyang memiliki dua properti namedan company.

class Person: NSObject {

    var name : String //Person must have a value so its no marked as optional
    var companyName : String? ///Company is optional as a person can be unemployed that is nil value is possible

    init(name:String,company:String?) {

        self.name = name
        self.companyName = company

    }
}

Sekarang mari kita buat beberapa objek Person

var tom:Person = Person.init(name: "Tom", company: "Apple")//posible
var bob:Person = Person.init(name: "Bob", company:nil) // also Possible because company is marked as optional so we can give Nil

Tapi kita tidak bisa lewat Nilkename

var personWithNoName:Person = Person.init(name: nil, company: nil)

Sekarang mari kita bicara tentang mengapa kita menggunakan optional?. Mari kita pertimbangkan situasi di mana kita ingin menambahkan Incsetelah nama perusahaan appleakan apple Inc. Kita perlu menambahkan Incsetelah nama perusahaan dan cetak.

print(tom.companyName+" Inc") ///Error saying optional is not unwrapped.
print(tom.companyName!+" Inc") ///Error Gone..we have forcefully unwrap it which is wrong approach..Will look in Next line
print(bob.companyName!+" Inc") ///Crash!!!because bob has no company and nil can be unwrapped.

Sekarang mari kita pelajari mengapa opsional terjadi.

if let companyString:String = bob.companyName{///Compiler safely unwrap company if not nil.If nil,no unwrap.

    print(companyString+" Inc") //Will never executed and no crash!!!
}

Mari kita ganti bobdengantom

if let companyString:String = tom.companyName{///Compiler safely unwrap company if not nil.If nil,no unwrap.

    print(companyString+" Inc") //Will never executed and no crash!!!
}

Dan Selamat! kami telah berurusan dengan benaroptional?

Jadi poin realisasi adalah

  1. Kami akan menandai variabel sebagai opsional jika memungkinkan nil
  2. Jika kita ingin menggunakan variabel ini di suatu tempat di kompiler kode akan mengingatkan Anda bahwa kami perlu memeriksa apakah kami telah menangani variabel itu dengan benar jika mengandung nil.

Terima kasih ... Selamat Coding

Tunvir Rahman Tusher
sumber
0

Mari Bereksperimen dengan kode Playground di bawah ini. Saya harap akan menjernihkan ide apa yang opsional dan alasan menggunakannya.

var sampleString: String? ///Optional, Possible to be nil

sampleString = nil ////perfactly valid as its optional

sampleString = "some value"  //Will hold the value

if let value = sampleString{ /// the sampleString is placed into value with auto force upwraped.

    print(value+value)  ////Sample String merged into Two
}

sampleString = nil // value is nil and the

if let value = sampleString{

    print(value + value)  ///Will Not execute and safe for nil checking
}

//   print(sampleString! + sampleString!)  //this line Will crash as + operator can not add nil
Tunvir Rahman Tusher
sumber
0

Dari https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/OptionalChaining.html :

Chaining opsional adalah proses untuk menanyakan dan memanggil properti, metode, dan subskrip pada opsional yang saat ini mungkin nol. Jika opsional berisi nilai, properti, metode, atau panggilan subskrip berhasil; jika opsional adalah nihil, properti, metode, atau panggilan subskrip mengembalikan nihil. Beberapa kueri dapat dirantai bersama, dan seluruh rantai gagal dengan anggun jika tautan apa pun dalam rantai nol.

Untuk memahami lebih dalam, baca tautan di atas.

nizama bunti
sumber
0

Baik...

? (Opsional) menunjukkan bahwa variabel Anda mungkin berisi nilai nil sementara ! (unwrapper) menunjukkan variabel Anda harus memiliki memori (atau nilai) ketika digunakan (mencoba untuk mendapatkan nilai dari itu) saat runtime.

Perbedaan utama adalah bahwa rantai opsional gagal dengan anggun ketika opsional adalah nol, sedangkan membuka paksa dipaksa memicu kesalahan runtime ketika opsional adalah nol.

Untuk mencerminkan fakta bahwa perangkaian opsional dapat dipanggil pada nilai nihil, hasil dari perangkaian panggilan opsional selalu merupakan nilai opsional, bahkan jika properti, metode, atau subskrip yang Anda query mengembalikan nilai non-opsional. Anda dapat menggunakan nilai pengembalian opsional ini untuk memeriksa apakah panggilan chaining opsional berhasil (opsional kembali berisi nilai), atau tidak berhasil karena nilai nol di rantai (nilai opsional yang dikembalikan adalah nol).

Secara khusus, hasil dari panggilan chaining opsional adalah jenis yang sama dengan nilai pengembalian yang diharapkan, tetapi dibungkus dengan opsional. Properti yang biasanya mengembalikan Int akan mengembalikan Int? ketika diakses melalui perangkaian opsional.

var defaultNil : Int?  // declared variable with default nil value
println(defaultNil) >> nil  

var canBeNil : Int? = 4
println(canBeNil) >> optional(4)

canBeNil = nil
println(canBeNil) >> nil

println(canBeNil!) >> // Here nil optional variable is being unwrapped using ! mark (symbol), that will show runtime error. Because a nil optional is being tried to get value using unwrapper

var canNotBeNil : Int! = 4
print(canNotBeNil) >> 4

var cantBeNil : Int = 4
cantBeNil = nil // can't do this as it's not optional and show a compile time error

Berikut ini adalah tutorial dasar secara rinci, oleh Komite Pengembang Apple: Chaining Opsional

Krunal
sumber
0

Opsional dalam Swift adalah jenis yang dapat menyimpan nilai atau tidak ada nilai. Opsional ditulis dengan menambahkan ? untuk semua jenis:

var name: String?

Anda dapat merujuk ke tautan ini untuk mendapatkan pengetahuan secara mendalam: https://medium.com/@agoiabeladeyemi/optionals-in-swift-2b141f12f870

Vicky Prajapati
sumber
-1

Berikut adalah deklarasi opsional yang setara di Swift:

var middleName: String?

Deklarasi ini membuat variabel bernama middleName of type String. Tanda tanya (?) Setelah tipe variabel String menunjukkan bahwa variabel middleName dapat berisi nilai yang bisa berupa String atau nihil. Siapa pun yang melihat kode ini segera tahu bahwa middleName dapat nihil. Ini mendokumentasikan diri!

Jika Anda tidak menentukan nilai awal untuk konstanta opsional atau variabel (seperti yang ditunjukkan di atas) nilai secara otomatis ditetapkan ke nol untuk Anda. Jika Anda suka, Anda dapat secara eksplisit mengatur nilai awal menjadi nihil:

var middleName: String? = nil

untuk lebih detail untuk tautan baca di bawah opsional

http://www.iphonelife.com/blog/31369/swift-101-working-swifts-new-optional-values

Devendra Agnihotri
sumber
gunakan ini, var middleName: String! = ""
Gaurav