Diberikan yang berikut di Swift:
var optionalString: String?
let dict = NSDictionary()
Apa perbedaan praktis antara dua pernyataan berikut:
optionalString = dict.objectForKey("SomeKey") as? String
vs.
optionalString = dict.objectForKey("SomeKey") as! String?
swift
optional
downcast
optional-variables
sdduursma
sumber
sumber
Jawaban:
Perbedaan praktisnya adalah ini:
optionalString
akan menjadi variabel tipeString?
. Jika tipe yang mendasarinya adalah sesuatu selain dariString
ini, ini tidak akan berbahaya hanya ditetapkannil
ke opsional.Ini mengatakan, saya tahu hal ini adalah a
String?
. Ini juga akan mengakibatkanoptionalString
menjadi tipeString?
, tetapi akan macet jika tipe yang mendasarinya adalah sesuatu yang lain.Gaya pertama kemudian digunakan dengan
if let
untuk membuka bungkus opsional dengan aman:sumber
as? Types
- berarti proses pengecoran turun adalah opsional. Proses bisa berhasil atau tidak (sistem akan mengembalikan nihil jika down casting gagal). Cara apapun tidak akan crash jika down casting gagal.as! Type?
- Di sini proses pengecoran harus berhasil (!
menunjukkan bahwa). Tanda tanya penutup menunjukkan apakah hasil akhirnya bisa nihil atau tidak.Info lebih lanjut tentang "!" dan "?"
Mari kita ambil 2 kasus
Mempertimbangkan:
Disini kita tidak tahu apakah hasil dari down casting cell dengan identifier "Cell" ke UITableViewCell berhasil atau tidak. Jika tidak berhasil maka mengembalikan nil (jadi kami menghindari crash di sini). Di sini kita dapat melakukan seperti yang diberikan di bawah ini.
Jadi mari kita mengingatnya seperti ini - Jika
?
itu berarti kita tidak yakin apakah nilainya nihil atau tidak (tanda tanya muncul ketika kita tidak tahu sesuatu).Bandingkan itu dengan:
Di sini kami memberi tahu kompiler bahwa pengecoran down harus berhasil. Jika gagal sistem akan macet. Jadi kita berikan
!
ketika kita yakin nilainya bukan nihil.sumber
Untuk memperjelas apa yang dikatakan vacawama, berikut adalah contohnya ...
Swift 3.0:
Swift 2.0:
sumber
intNil as! String? // ==nil
tidak menyebabkan crash !!! ???, sebagai Opsional <Int>. Tidak ada yang berbeda dari Opsional <String> .Noneas?
keString
? Mengapa Anda tidak merendahkannyaString?
? Mengapa tidak kau tertundukas!
keString
?Any
alih-alihAnyObject
as
digunakan untuk upcasting dan tipe casting untuk tipe bridgedas?
digunakan untuk casting yang aman, kembalikan nihil jika gagalas!
digunakan untuk memaksa casting, crash jika gagalcatatan:
as!
tidak dapat mengubah tipe mentah menjadi opsionalContoh:
Contoh
Dengan menambahkan ? segera setelah tipe data Anda memberi tahu compiler bahwa variabel mungkin berisi angka atau tidak. Rapi! Perhatikan bahwa tidak masuk akal untuk mendefinisikan konstanta Opsional - Anda dapat menyetel nilainya hanya sekali dan oleh karena itu Anda akan dapat mengatakan apakah nilainya akan menjadi nil atau tidak.
Kapan kita harus menggunakan "?" dan kapan "!"
katakanlah kita memiliki aplikasi sederhana berbasis UIKit. kami memiliki beberapa kode di pengontrol tampilan kami dan ingin menampilkan pengontrol tampilan baru di atasnya. dan kami perlu memutuskan untuk menampilkan tampilan baru di layar menggunakan pengontrol navigasi.
Seperti yang kita ketahui, setiap instance ViewController memiliki pengontrol navigasi properti. Jika Anda membangun aplikasi berbasis pengontrol navigasi, properti pengontrol tampilan utama aplikasi Anda disetel secara otomatis dan Anda dapat menggunakannya untuk mendorong atau memunculkan pengontrol tampilan. Jika Anda menggunakan template proyek aplikasi tunggal - tidak akan ada pengontrol navigasi yang dibuat secara otomatis untuk Anda, sehingga pengontrol tampilan default aplikasi Anda tidak akan menyimpan apa pun di properti navigationController.
Saya yakin Anda sudah menebak bahwa ini persis kasus untuk tipe data Opsional. Jika Anda memeriksa UIViewController Anda akan melihat bahwa properti tersebut didefinisikan sebagai:
Jadi mari kita kembali ke kasus penggunaan kita. Jika Anda mengetahui fakta bahwa pengontrol tampilan Anda akan selalu memiliki pengontrol navigasi, Anda dapat melanjutkan dan membukanya secara paksa:
Saat Anda meletakkan! di belakang nama properti Anda memberi tahu kompiler Saya tidak peduli bahwa properti ini opsional, saya tahu bahwa ketika kode ini dijalankan akan selalu ada penyimpanan nilai jadi perlakukan Opsional ini seperti tipe data normal. Bukankah itu bagus? Apa yang akan terjadi jika tidak ada pengontrol navigasi ke pengontrol tampilan Anda? Jika saran Anda bahwa akan selalu ada nilai yang disimpan di navigationController salah? Aplikasi Anda akan mogok. Sederhana dan jelek seperti itu.
Bagaimana jika Anda tidak yakin bahwa akan selalu ada pengontrol navigasi? Lalu Anda bisa menggunakan? bukannya!:
Apa itu? di belakang nama properti memberitahu kompiler adalah Saya tidak tahu apakah properti ini berisi nil atau nilai, jadi: jika memiliki nilai, gunakan itu, dan jika tidak, pertimbangkan seluruh ekspresi nil.Secara efektif? memungkinkan Anda menggunakan properti itu kalau-kalau ada pengontrol navigasi. Tidak, jika pemeriksaan dalam bentuk apa pun atau coran apa pun. Sintaks ini sempurna saat Anda tidak peduli apakah Anda memiliki pengontrol navigasi atau tidak, dan ingin melakukan sesuatu hanya jika ada.
Terima kasih banyak untuk Fantageek
sumber
Mereka adalah dua bentuk Downcasting yang berbeda di Swift.
(
as?
) , yang dikenal sebagai Formulir Bersyarat , mengembalikan nilai opsional dari jenis yang Anda coba untuk downcast.(
as!
) , yang dikenal sebagai Bentuk Paksa , mencoba downcast dan memaksa-membuka hasilnya sebagai aksi gabungan tunggal.Untuk lebih jelasnya, silakan periksa bagian Type Casting di dokumentasi Apple.
sumber
Mungkin contoh kode ini akan membantu seseorang memahami prinsip:
sumber
Yang pertama adalah "pemeran bersyarat" (lihat di bawah "operator pengecoran tipe" dalam dokumentasi yang saya tautkan) . Jika cast berhasil, nilai ekspresi dibungkus dalam opsional dan dikembalikan, jika tidak, nilai yang dikembalikan adalah nihil.
Yang kedua berarti bahwa optionalString bisa berupa objek string atau mungkin nihil.
Informasi lebih lanjut ditemukan dalam pertanyaan terkait ini .
sumber
Mungkin paling mudah untuk mengingat pola untuk operator ini di Swift karena:
!
menyiratkan "ini mungkin menjebak," sementara?
menunjukkan "ini mungkin nihil."lihat: https://developer.apple.com/swift/blog/?id=23
sumber
Saya pemula di Swift dan menulis contoh ini mencoba menjelaskan seperti yang saya mengerti tentang 'pilihan'. Jika saya salah tolong perbaiki saya.
Terima kasih.
(1):
obj.lastName = obj.lName as! String
vs.
(2):
obj.lastName = obj.lName as? String
Jwb: (1) Disini programmer pasti yakin
“obj.lName”
berisi object bertipe string. Jadi berikan saja nilai itu“obj.lastName”
.Nah, jika programmer benar berarti
"obj.lName"
objek bertipe string, maka tidak masalah. "obj.lastName" akan disetel ke nilai yang sama.Tapi kalau programmer salah artinya
"obj.lName"
bukan objek bertipe string yaitu berisi beberapa objek tipe lain seperti "NSNumber" dll. Kemudian CRASH (Run Time Error).(2) Programmer tidak yakin yang
“obj.lName”
berisi objek tipe string atau objek tipe lainnya. Jadi atur nilai itu menjadi“obj.lastName”
jika itu adalah tipe string.Nah, jika programmer benar berarti
“obj.lName”
objek bertipe string, maka tidak masalah.“obj.lastName”
akan disetel ke nilai yang sama.Tetapi jika programmer salah berarti obj.lName bukanlah objek bertipe string yaitu berisi beberapa objek tipe lain seperti
"NSNumber"
dll. Kemudian“obj.lastName”
akan diset ke nilai nil. Jadi, No Crash (Happy :)sumber