Saat saya ingin memeriksa apakah Opsional Bool benar, melakukan ini tidak berhasil:
var boolean : Bool? = false
if boolean{
}
Ini menghasilkan kesalahan ini:
Jenis opsional '@IvalueBool?' tidak dapat digunakan sebagai boolean; uji untuk '! = nil' sebagai gantinya
Saya tidak ingin memeriksa nol; Saya ingin memeriksa apakah nilai yang dikembalikan benar.
Apakah saya selalu harus melakukannya if boolean == true
jika saya bekerja dengan Opsional Bool?
Karena Opsional tidak sesuai BooleanType
lagi, bukankah kompiler harus tahu bahwa saya ingin memeriksa nilai Bool?
Jawaban:
Dengan boolean opsional, diperlukan pemeriksaan yang eksplisit:
if boolean == true { ... }
Jika tidak, Anda dapat membuka bungkus opsional:
if boolean! { ... }
Tapi itu menghasilkan pengecualian waktu proses jika boolean adalah
nil
- untuk mencegahnya:if boolean != nil && boolean! { ... }
Sebelum beta 5 itu mungkin, tetapi itu telah diubah seperti yang dilaporkan dalam catatan rilis:
Tambahan: seperti yang disarankan oleh @MartinR, variasi yang lebih ringkas untuk opsi ke-3 menggunakan operator penggabungan:
if boolean ?? false { // this code runs only if boolean == true }
yang berarti: jika boolean bukan nil, ekspresi mengevaluasi ke nilai boolean (yaitu menggunakan nilai boolean yang tidak dibungkus), jika tidak ekspresi mengevaluasi ke
false
sumber
if let
juga akan berhasil.if boolean ?? false { ... }
.if !(boolean ?? true) { ... }
:(Penjilidan opsional
Cepat 3 & 4
var booleanValue : Bool? = false if let booleanValue = booleanValue, booleanValue { // Executes when booleanValue is not nil and true // A new constant "booleanValue: Bool" is defined and set print("bound booleanValue: '\(booleanValue)'") }
Swift 2.2.0
var booleanValue : Bool? = false if let booleanValue = booleanValue where booleanValue { // Executes when booleanValue is not nil and true // A new constant "booleanValue: Bool" is defined and set print("bound booleanValue: '\(booleanValue)'") }
Kode
let booleanValue = booleanValue
kembalifalse
jikabooleanValue
adanil
danif
blok tidak dijalankan. JikabooleanValue
tidaknil
, kode ini mendefinisikan variabel baru bernamabooleanValue
tipeBool
(bukan opsional,Bool?
).Kode Swift 3 & 4
booleanValue
(dan kode Swift 2.2where booleanValue
) mengevaluasibooleanValue: Bool
variabel baru . Jika benar,if
blok dijalankan denganbooleanValue: Bool
variabel yang baru didefinisikan dalam cakupan (memungkinkan opsi untuk mereferensikan nilai terikat lagi di dalamif
blok).Catatan: Ini adalah konvensi Swift untuk menamai konstanta / variabel terikat sama dengan konstanta / variabel opsional seperti
let booleanValue = booleanValue
. Teknik ini disebut variabel shadowing . Anda bisa keluar dari konvensi dan menggunakan sesuatu sepertilet unwrappedBooleanValue = booleanValue, unwrappedBooleanValue
. Saya menunjukkan ini untuk membantu memahami apa yang terjadi. Saya merekomendasikan menggunakan variabel shadowing.Pendekatan Lainnya
Penggabungan nol
Penggabungan nol jelas untuk kasus khusus ini
var booleanValue : Bool? = false if booleanValue ?? false { // executes when booleanValue is true print("optional booleanValue: '\(booleanValue)'") }
Memeriksa
false
tidak begitu jelasvar booleanValue : Bool? = false if !(booleanValue ?? false) { // executes when booleanValue is false print("optional booleanValue: '\(booleanValue)'") }
Catatan:
if !booleanValue ?? false
tidak dapat dikompilasi.Paksa buka bungkus opsional (hindari)
Buka paksa bungkusnya meningkatkan kemungkinan bahwa seseorang akan membuat perubahan di masa mendatang yang terkompilasi tetapi mengalami error saat runtime. Oleh karena itu, saya akan menghindari hal seperti ini:
var booleanValue : Bool? = false if booleanValue != nil && booleanValue! { // executes when booleanValue is true print("optional booleanValue: '\(booleanValue)'") }
Pendekatan Umum
Meskipun pertanyaan stack overflow ini menanyakan secara spesifik bagaimana cara memeriksa apakah a
Bool?
adatrue
dalamif
pernyataan, akan sangat membantu untuk mengidentifikasi pendekatan umum apakah memeriksa true, false, atau menggabungkan nilai yang tidak dibungkus dengan ekspresi lain.Karena ungkapan menjadi lebih rumit, saya menemukan pendekatan penjilidan opsional lebih fleksibel dan lebih mudah dipahami daripada pendekatan lain. Perhatikan bahwa karya mengikat opsional dengan jenis opsional (
Int?
,String?
, dll).sumber
if let
?while array.last < threshold { array.removeLast() }
if, let, where
menggunakan ini:while let last = array.last where last < threshold { array.removeLast() }
di Swift 2 atauwhile let last = array.last, last < threshold { array.removeLast() }
di Swift 3.while let
.var enabled: Bool? = true if let enabled = enabled, enabled == true { print("when is defined and true at the same moment") } if enabled ?? false { print("when is defined and true at the same moment") } if enabled == .some(true) { print("when is defined and true at the same moment") } if enabled == (true) { print("when is defined and true at the same moment") } if case .some(true) = enabled { print("when is defined and true at the same moment") } if enabled == .some(false) { print("when is defined and false at the same moment") } if enabled == (false) { print("when is defined and false at the same moment") } if enabled == .none { print("when is not defined") } if enabled == nil { print("when is not defined") }
sumber
Saya menemukan solusi lain, membebani operator Boolean. Sebagai contoh:
public func < <T: Comparable> (left: T?, right: T) -> Bool { if let left = left { return left < right } return false }
Ini mungkin tidak sepenuhnya dalam "semangat" perubahan bahasa, tetapi memungkinkan untuk membuka bungkus opsional dengan aman, dan dapat digunakan untuk kondisi di mana saja, termasuk while loop.
sumber
Jawaban yang menurut saya paling mudah dibaca adalah dengan mendefinisikan suatu fungsi. Tidak terlalu rumit tetapi berhasil.
func isTrue(_ bool: Bool?) -> Bool { guard let b = bool else { return false } return b }
pemakaian:
let b: Bool? = true if isTrue(b) { // b exists and is true } else { // b does either not exist or is false }
sumber
Seperti kata Antonio
Saya menghabiskan beberapa jam mencoba memahami sebaris kode yang saya temukan, tetapi utas ini menempatkan saya di jalur yang benar.
Kutipan ini dari Agustus 2014 , dan sejak itu Apple memperkenalkan
Never
berikut usulan SE-0102 dan yang terakhir dibuat sesuai dengan equatable, Hashable, Kesalahan dan SebandingSekarang dimungkinkan untuk memeriksa apakah boolean
nil
menggunakanNever?
:var boolean: Bool? = false boolean is Never? // false boolean = true boolean is Never? // false boolean = nil boolean is Never? // true
Anda sebenarnya dapat menggunakan jenis lain yang tidak bisa dihuni :
public enum NeverEver { } var boolean: Bool? = false boolean is NeverEver? // false boolean = true boolean is NeverEver? // false boolean = nil boolean is NeverEver? // true
Karena itu, Anda juga dapat menggunakan pembungkus properti sekarang:
@propertyWrapper struct OptionalBool { public var wrappedValue: Bool? public var projectedValue: Bool { wrappedValue ?? false } public init(wrappedValue: Bool?) { self.wrappedValue = wrappedValue } } struct Struct { @OptionalBool var predicate: Bool? var description: String { if $predicate { return "predicate is true" } return "predicate is false" } } var object = Struct() object.description // "predicate is false" object.predicate = false object.description // "predicate is false" object.predicate = true object.description // "predicate is true"
atau bahkan:
@propertyWrapper struct OptionalBool { var wrappedValue: Bool? var projectedValue: OptionalBool { self } var isNil: Bool { wrappedValue is Never? } var value: Bool { wrappedValue ?? false } init(wrappedValue: Bool?) { self.wrappedValue = wrappedValue } } struct Struct { @OptionalBool var predicate: Bool? var description: String { if $predicate.value { return "predicate is true" } if !$predicate.isNil { return "predicate is false" } return "predicate is nil" } } var object = Struct() object.description // "predicate is nil" object.predicate = false object.description // "predicate is false" object.predicate = true object.description // "predicate is true"
sumber