2015-10-01 9 views
6

Więc w Objective-C przy użyciu logicznych jest to możliwe, i zachęcać do pisania kodu przy użyciu zmiennej wartość niezerową, jak jest to wartość logiczna, co oznacza, że ​​można napisać kod jak poniżej:Swift Boolean sprawdzanie

if (someBool) { 
    // Stuff 
} 

Ponadto, istnieją powody, dla których kod jak poniżej jest odradzane:

if (someBool == YES) { 
    // Might run into problems here 
} 

powody sprawdzanie logiczną przeciwko innemu boolean są lepiej wyjaśnione here, ale krótko sprawa jest tak, że kiedy jesteś porównując równości do YES lub NO bezpośrednio, w rzeczywistości porównujesz odpowiednio z 1 i 0. Ponieważ Objective-C pozwala na użycie wartości niezerowych jako wartości prawdziwej, możesz skończyć porównywanie czegoś, co powinno być uznane za prawdziwe względem YES i mieć wyrażenie, które zostanie rozwiązane na NO, np.

int trueNumber = 2; 
if (trueNumber == YES) { 
    // Doesn't run because trueNumber != 1 
} 

Czy to nadal problem w Swift? Odłóż problemy z kodem, jeśli widzę coś podobnego do następującego: czy to będzie problem, czy też to naprawdę nie ma znaczenia? Czy te porównania w stylu C nadal występują pod maską, czy jest coś wbudowanego w Swift BooleanType, który zapobiega tym problemom?

Odpowiedz

2

Struktura w Swift if <something> {} wymaga <something> aby były zgodne z protokołem BooleanType który jest zdefiniowane w ten sposób:

public protocol BooleanType { 
    /// The value of `self`, expressed as a `Bool`. 
    public var boolValue: Bool { get } 
} 

Jeśli typ nie jest zgodny z tym protokołem, wystąpił błąd podczas kompilacji n. Jeśli szukasz tego protokołu w standardowej bibliotece, okaże się, że jedynym typem, który jest zgodny z tym protokołem, jest sama Bool. Bool to typ, który może być true lub false. Nie myśl o tym jako o numerze 1 lub 0, ale raczej jako On/Off Right/Wrong.

Teraz ten protokół można upodobnić się przez wszelkiego rodzaju nominalnej chcesz, np

extension Int : BooleanType { 
    public var boolValue : Bool { 
     return self > 0 
    } 
} 

Teraz, jeśli to zrobić (nie należy uczciwie), jesteś zdefiniowania go przez siebie, co „Prawda "i" Fałsz "oznacza. Teraz byłbyś w stanie wykorzystać go jak to (znowu, nie rób tego):

if 0 { 
    ... 
} 
+0

Dobra, więc powodem, dla którego kod, który stanowił problem w Objective-C, nie jest problem ze względu na ścisłe sprawdzanie typu w Swift? Wygląda na to, że aby używać go w logicznych kontrolach w Swift, typ w zasadzie musi zwracać ściśle wpisany 'Bool' (jak pokazano powyżej), co pozwala uniknąć problemu, który C i Objective-C miał z' typedef signed char''. Czy to jest tak proste? – Ziewvater

+0

@ Ziewvater Yup, popraw – Kametrixom

2

Swift ma typ Bool. Różni się to od BOOL obiektu-c, który nie jest faktycznym typem. Jest to właściwie typedef, niepodpisany znak. Kiedy Swift oczekuje Bool, musisz nadać mu Bool, inaczej jest to błąd kompilacji. Poniższy kod nie będzie kompilować bo wyboru nie jest Bool

let check = 2 
if check { 
} 

Ale to będzie działać, ponieważ == zwraca Bool

let check = 2 
if check == 2 { 
} 
+0

Właściwie 'Bool' jest jego własny rodzaj w Swift i * nie * typ alias" unsigned char "(który będzie" CUnsignedChar "w Swift). –

+0

Niestety mam na myśli Objective-C not swift – mustafa

+0

Cóż, jest bardziej skomplikowany w Objective-C, porównaj http://stackoverflow.com/questions/31267325/bool-with-64-bit-on-ios. –

0

Aby zrozumieć styl objc, trzeba wrócić do C.W C, to stwierdzenie:

if (something) { 
    // Do something 
} 

oceni do false jeśli something jest zerowy lub 0. Wszystko inne oceny do true. Problem polega na tym, że C nie ma typu boolowskiego. Objective-C i dodaje YESNO który jest w zasadzie 1 i 0. Tak więc:

if (aBoolValue == YES) { } // Work as expected 
if (anIntValue == YES) { } // False unless anIntValue == 1 

W „zniechęcać” zalecenie było dostosowanie do zachowania w C. Swift nie ma takich wymagań kompatybilności wstecz. Nie możesz pisać nich:

Zamiast wyrażenie musi ocenić wartość logiczna:

if anIntValue != 0 { } // Ok 
if anObject != nil { } // Ok