2011-07-12 15 views
14

Rozglądam się nad wersjami przesłanymi do projektu przez innego programistę i mają one dużo kodu, który ma !!<some BOOL value>. W rzeczywistości wydaje się, że jest to ich standardowy wzorzec do implementacji Boolean pobierających i ustawiających. Zaimplementowali swój kod:Objective-C - Jest !! BOOL Beneficial

- (BOOL) hasId { 
    return !!hasId_; 
} 
- (void) setHasId:(BOOL) value { 
    hasId_ = !!value; 
} 

Nigdy wcześniej nie widziałem tego wzoru i zastanawiam się, czy jest jakaś korzyść z jego używania. Czy podwójna negacja robi coś pożytecznego?

+0

tylko raz widziałem, że było to dla klasy, która nie miała prostego sposobu rzucania do boola, więc nie mogli zrobić 'if (myInstance)', ale przeciążyła jednoargumentowy operator '!' , więc zrobiliby "if (!! myInstance)". Ale w twoim przypadku nie mam pojęcia. – filipe

Odpowiedz

13

Podwójna operator logiczna tylko upewnia się, że wartość zwracana jest albo 1 albo 0. To wszystko:)

+5

... co zapobiega kodom takim jak "obj.hasId = 42; if (obj.hasId == YES) 'od niepowodzenia warunku. Technicznie "TAK" jest (obecnie) zamapowane na 1, więc wartości całkowite są różne. Koncepcyjnie jednak zarówno 42, jak i "YES" reprezentują prawdziwą wartość boolowską. Podwójna negacja zwija to 42-przypisanie do zadania "TAK". –

+0

Dzięki, założyłem, że to prawdopodobnie coś takiego. Ale czy jest to przydatne, aby to zrobić/czy uniknięto potencjalnych błędów?Być może to zapobiega nieoczekiwanym błędom podczas porównywania w postaci 'if (obj.hasId == YES)'? Chociaż i tak nie ma takiego porównania w złym stylu? Edit: nevermind, Bavarious mnie bił. – aroth

+0

To prawda, ale czasami jest to pomocne, aby przekonwertować na 1 lub 0, tak jak SQLite zapisuje pola logiczne tylko w 1 lub 0. –

3

! jest logiczną operator negacji. Więc jeśli setHasId: został przekazany, np. 0x2, wówczas podwójna negacja przechowałaby 0x1.

1

Jest to odpowiednik:

hasId_ = value ? 1 : 0; 

Jest to przydatne w niektórych przypadkach, ponieważ jeśli to zrobić:

BOOL x = y & MY_FLAG; 

Można dostać 0 jeśli MY_FLAG jest ustawiona, ponieważ wynik zostanie obcięty rozmiar BOOL (8 bitów). To nieoczekiwane. Z tych samych powodów ludzie czasami wolą, aby BOOL było 0 lub 1 (więc operacje bitowe działają zgodnie z oczekiwaniami). Zwykle jest to niepotrzebne.

W językach z wbudowanym typem bool, takim jak C (od C99) i C++, konwersja liczby całkowitej na bool powoduje to automatycznie.

0

To ma większy sens w niektórych innych przypadkach, na przykład, gdzie są powracających BOOL ale nie chcą umieścić oświadczenie if w.

- (BOOL)isMyVarSet 
{ 
    return !!myVar; 
} 

W tym przypadku nie mogę po prostu wrócić myVar bo to nie jest to BOOL (jest to bardzo wymyślny przykład - nie mogę wykopać przyzwoitego z moich projektów).

0

Użyłem tego wcześniej i wierzę:

if (!!myVar)

odpowiada:

if (myVar != nil)

Zasadniczo używam go zweryfikować wartość czegoś.

Przyznaję ... to prawdopodobnie nie jest najlepsza praktyka lub najbardziej zrozumiały sposób na osiągnięcie tego celu.

+0

Różnica jest następująca: (myVar! = Zero) jest dość oczywista, podczas gdy (!! myVar) zatrzymuje Cię w twoich śladach, musisz myśleć ciężko, co robi, i wtedy musisz myśleć jeszcze trudniej dowiedzieć się, czy ktokolwiek to napisał, tak naprawdę to znaczy. Najlepiej jasno wyrazić, co masz na myśli. – gnasher729

+0

Całkowicie się zgadzam! Moja odpowiedź to 3 lata, a ABSOLUTNIE nie napisałbym! Var w nowym kodzie już dziś! – mbm29414