Saya sedang belajar Swift untuk iOS 8 / OSX 10.10 dengan mengikuti tutorial ini , dan istilah " nilai terbuka " digunakan beberapa kali, seperti pada paragraf ini (di bawah Objek dan Kelas ):
Ketika bekerja dengan nilai-nilai opsional, Anda dapat menulis? sebelum operasi seperti metode, properti, dan berlangganan. Jika nilainya sebelum? adalah nihil, semuanya setelah? diabaikan dan nilai keseluruhan ekspresi adalah nihil. Jika tidak, nilai opsional tidak terbuka , dan semuanya setelah? bertindak berdasarkan nilai yang tidak terbuka . Dalam kedua kasus, nilai keseluruhan ekspresi adalah nilai opsional.
let optionalSquare: Square? = Square(sideLength: 2.5, name: "optional square")
let sideLength = optionalSquare?.sideLength
Saya tidak mengerti, dan mencari di web tanpa hasil.
Apa artinya ini?
Edit
Dari jawaban Cezary, ada sedikit perbedaan antara output dari kode asli dan solusi akhir (diuji di taman bermain):
Kode asli
Solusi Cezary
Properti superclass ditampilkan dalam output dalam kasus kedua, sementara ada objek kosong dalam kasus pertama.
Bukankah hasilnya seharusnya sama dalam kedua kasus?
T&J terkait: Berapakah nilai opsional di Swift?
Jawaban:
Pertama, Anda harus memahami apa jenis Opsional. Tipe opsional pada dasarnya berarti bahwa variabel tersebut dapat
nil
.Contoh:
Tanda tanya menunjukkan fakta yang
canBeNil
bisanil
.Ini tidak akan berfungsi:
Untuk mendapatkan nilai dari variabel Anda jika itu opsional, Anda harus membuka bungkusnya . Ini berarti menempatkan tanda seru di bagian akhir.
Kode Anda akan terlihat seperti ini:
Sidenote:
Anda juga dapat mendeklarasikan opsi untuk membuka secara otomatis dengan menggunakan tanda seru alih-alih tanda tanya.
Contoh:
Jadi cara alternatif untuk memperbaiki kode Anda adalah:
EDIT:
Perbedaan yang Anda lihat adalah persis gejala fakta bahwa nilai opsional dibungkus . Ada lapisan lain di atasnya. Versi yang tidak terbuka hanya menunjukkan objek yang lurus karena, yah, tidak terbuka.
Perbandingan bermain cepat:
Dalam kasus pertama dan kedua, objek tidak secara otomatis dibuka, sehingga Anda melihat dua "lapisan" (
{{...}}
), sedangkan dalam kasus ketiga, Anda hanya melihat satu lapisan ({...}
) karena objek sedang dibuka secara otomatis.Perbedaan antara kasing pertama dan kasing kedua adalah bahwa kasing kedua akan memberikan Anda kesalahan runtime jika
optionalSquare
diatur kenil
. Menggunakan sintaks dalam kasus pertama, Anda dapat melakukan sesuatu seperti ini:sumber
init()
fungsi kelas. Saya merekomendasikan membaca bab "Dasar-Dasar" (mencakup opsional), "Inisialisasi", dan "Rantai Opsional" dalam buku Swift yang dirilis oleh Apple.Jawaban yang benar yang ada sangat bagus, tetapi saya menemukan bahwa bagi saya untuk memahami ini sepenuhnya, saya memerlukan analogi yang baik, karena ini adalah konsep yang sangat abstrak dan aneh.
Jadi, izinkan saya membantu pengembang (berpikir visual) sesama "berotak kanan" dengan memberikan perspektif berbeda selain jawaban yang benar. Ini analogi bagus yang banyak membantu saya.
Analogi Pembungkus Hadiah Ulang Tahun
Pikirkan opsional sebagai hadiah ulang tahun yang datang dalam pembungkus yang kaku, keras, berwarna.
Anda tidak tahu apakah ada sesuatu di dalam bungkus sampai Anda membuka kado - mungkin tidak ada apa-apa di dalamnya! Jika ada sesuatu di dalamnya, itu bisa jadi hadiah lain, yang juga dibungkus, dan yang juga mungkin tidak mengandung apa pun . Anda bahkan dapat membuka 100 hadiah bersarang untuk akhirnya menemukan tidak ada yang lain selain membungkus .
Jika nilai opsional tidak
nil
, sekarang Anda telah mengungkapkan kotak yang berisi sesuatu . Tetapi, terutama jika nilainya tidak diketik secara eksplisit dan merupakan variabel dan bukan konstanta yang telah ditentukan, maka Anda mungkin masih perlu membuka kotak sebelum Anda dapat mengetahui sesuatu yang spesifik tentang apa yang ada di dalam kotak, seperti apa jenisnya , atau apa nilai sebenarnya adalah.Apa yang ada di dalam kotak?! Analogi
Bahkan setelah Anda membuka variabel, Anda masih seperti Brad Pitt di adegan terakhir di SE7EN ( peringatan : spoiler dan bahasa kasar dan kekerasan R-rated), karena bahkan setelah Anda membuka bungkusan saat ini, Anda berada dalam situasi berikut: Anda sekarang memiliki
nil
, atau kotak yang berisi sesuatu (tetapi Anda tidak tahu apa).Anda mungkin tahu jenis sesuatu . Misalnya, jika Anda mendeklarasikan variabel sebagai tipe,
[Int:Any?]
maka Anda akan tahu bahwa Anda memiliki Kamus (berpotensi kosong) dengan subskrip integer yang menghasilkan konten terbungkus dari semua tipe lama.Itu sebabnya berurusan dengan jenis koleksi (Kamus dan Array) di Swift bisa menjadi agak berbulu.
Inti masalah:
sumber
Swift menempatkan premi tinggi pada keamanan jenis. Seluruh bahasa Swift dirancang dengan mempertimbangkan keselamatan. Ini adalah salah satu ciri khas Swift dan yang harus Anda sambut dengan tangan terbuka. Ini akan membantu dalam pengembangan kode yang bersih dan mudah dibaca serta membantu menjaga aplikasi Anda agar tidak macet.
Semua opsional di Swift ditandai dengan
?
simbol. Dengan mengatur?
setelah nama tipe yang Anda deklarasikan sebagai opsional, Anda pada dasarnya casting ini bukan sebagai tipe yang sebelum?
, tetapi sebagai tipe opsional .Menggunakan Opsional
Ini tidak berarti bahwa Anda bekerja dengan tipe
String
. Ini berarti bahwa Anda bekerja dengan jenisString?
(String Opsional, atau Opsional String). Bahkan, kapan pun Anda berusahasaat runtime, konsol debug akan dicetak
Optional("foobar")
. Bagian "Optional()
" menunjukkan bahwa variabel ini mungkin atau mungkin tidak memiliki nilai saat runtime, tetapi kebetulan saat ini mengandung string "foobar".Optional()
Indikasi ini " " akan tetap kecuali Anda melakukan apa yang disebut "membuka" nilai opsional.Membuka gulungan suatu opsi berarti bahwa Anda sekarang menggunakan tipe itu sebagai non-opsional. Ini akan menghasilkan tipe baru dan menetapkan nilai yang berada di dalam opsional itu ke jenis non-opsional baru. Dengan cara ini Anda dapat melakukan operasi pada variabel itu karena telah dijamin oleh kompiler untuk memiliki nilai yang solid.
Dibuka dengan syarat akan memeriksa apakah nilai dalam opsional
nil
atau tidak. Jika tidaknil
, akan ada variabel konstan yang baru dibuat yang akan diberi nilai dan dibuka ke konstanta non-opsional. Dan dari sana Anda dapat dengan aman menggunakan non-opsional diif
blok.Opsional yang terbuka secara kondisional adalah cara terbersih untuk mengakses nilai opsional karena jika mengandung nilai nil maka semua yang ada di dalam blok if let tidak akan dieksekusi. Tentu saja, seperti pernyataan if apa pun, Anda dapat menyertakan blok lain
Membuka paksa secara paksa dilakukan dengan menggunakan apa yang dikenal sebagai
!
operator ("bang"). Ini kurang aman tetapi masih memungkinkan kode Anda untuk dikompilasi. Namun setiap kali Anda menggunakan operator bang Anda harus yakin 1000% bahwa variabel Anda sebenarnya mengandung nilai yang solid sebelum membuka paksa.Ini di atas sepenuhnya kode Swift yang valid. Mencetak nilai
myString
yang ditetapkan sebagai "foobar". Pengguna akan melihatfoobar
tercetak di konsol dan hanya itu saja. Tapi mari kita asumsikan nilainya tidak pernah ditetapkan:Sekarang kami memiliki situasi yang berbeda di tangan kami. Tidak seperti Objective-C, setiap kali ada upaya untuk membuka paksa opsional, dan opsional belum diatur dan
nil
, ketika Anda mencoba untuk membuka opsional untuk melihat apa yang ada di dalam aplikasi Anda akan crash.Buka gulungan dg Tipe Casting . Seperti yang telah kami katakan sebelumnya bahwa meskipun Anda adalah
unwrapping
opsional, Anda benar-benar melakukan casting ke tipe non-opsional, Anda juga dapat melemparkan non-opsional ke jenis yang berbeda. Sebagai contoh:Di suatu tempat dalam kode kita, variabel
something
akan diatur dengan beberapa nilai. Mungkin kita menggunakan obat generik atau mungkin ada logika lain yang terjadi yang akan menyebabkan ini berubah. Jadi nanti dalam kode kita, kita ingin menggunakansomething
tetapi masih dapat memperlakukannya secara berbeda jika itu adalah jenis yang berbeda. Dalam hal ini Anda ingin menggunakanas
kata kunci untuk menentukan ini:Perhatikan perbedaan antara kedua
as
kata kunci tersebut. Seperti sebelumnya ketika kami secara paksa membuka bungkusan opsional, kami menggunakan!
operator letusan untuk melakukannya. Di sini Anda akan melakukan hal yang sama tetapi alih-alih melakukan casting sebagai non-opsional, Anda juga melakukan castingInt
. Dan itu harus dapat dibatalkan karenaInt
, jika tidak, seperti menggunakan operator bang ketika nilainyanil
aplikasi Anda akan crash.Dan untuk menggunakan variabel-variabel ini sama sekali dalam semacam operasi matematika mereka harus dibuka untuk melakukannya.
Sebagai contoh, dalam Swift hanya tipe data angka yang valid dari jenis yang sama dapat dioperasikan satu sama lain. Ketika Anda melemparkan sebuah tipe dengan
as!
Anda memaksa downcast variabel itu seolah-olah Anda yakin itu adalah tipe itu, karena itu aman untuk beroperasi dan tidak crash aplikasi Anda. Ini boleh saja asalkan variabelnya memang dari tipe yang Anda gunakan, jika tidak, Anda akan memiliki kekacauan di tangan Anda.Meskipun demikian casting dengan
as!
akan memungkinkan kode Anda untuk dikompilasi. Dengan casting denganas?
cerita yang berbeda. Bahkan,as?
nyatakan bahwa AndaInt
adalah tipe data yang sama sekali berbeda.Sekarang sudah
Optional(0)
Dan jika Anda pernah mencoba mengerjakan pekerjaan rumah Anda menulis sesuatu seperti
Guru matematika Anda kemungkinan memberi Anda "F". Sama dengan Swift. Kecuali Swift lebih suka tidak mengkompilasi sama sekali daripada memberi Anda nilai. Karena pada akhirnya hari opsional mungkin sebenarnya nol .
Safety First Kids.
sumber
' berarti ekspresi rantai opsional
'berarti' adalah nilai gaya
sumber