2016-02-22 8 views
13

że typ Optional w Swift jest bezpieczniejszy niż nil w Objective-C, ale nie rozumiem, dlaczego tak się dzieje.Co sprawia, że ​​"Optional" Swifta jest bezpieczniejsze niż "zero" w Objective-C?

Jakie są istotne różnice w implementacji, które czynią Optional s bezpieczniejszymi niż nil i jak wpłynie to na mój kod?

+9

Swift nie obsługuje zera poza opcją Opcjonalnie. Opcjonalne może zawierać zero, a nie-Opcjonalne nie może zawierać zera. Jeśli zadeklarujesz zmienną jako nieopisaną rozpakowaną za pomocą "!", Jeśli zmienna zawiera zero, gdy z niej skorzystasz, otrzymasz wyjątek. Dlatego nie musisz radzić sobie ze zmienną "magicznie" zawierającą zero, gdy się jej nie spodziewasz. – Michael

+0

@Michael Twój komentarz działa jako odpowiedź. –

Odpowiedz

3

Zawsze sprawdzam, czy zmienna to nil, zanim użyję jej, aby uniknąć problemów. Jednak zdarza się, że od czasu do czasu wartość może się wydarzyć jako nil, a czasem po prostu zapomnę sprawdzić.

Po tym, jak koduję coraz więcej w Swift, stwierdziłem, że używanie opcjonalnych zmiennych rzeczywiście zapewnia dużą wygodę, aby uniknąć ignorowania wartości sprawdzania dla wartości nil. Naprawdę nie pamiętam żadnych awarii z powodu zmiennego dostępu nil (chyba że wymuszam rozpakowanie jakiejś zmiennej, więc nie wymuszaj rozpakowywania, chyba że wiesz co robisz).

Poza tym kiedyś napisać dużo kodu takich jak to w wielu miejscach:

if (obj != nil) { 
    obj.property = ... 
} 

Teraz mogę po prostu zrobić jak

obj?.property = ... 

kod teraz wygląda czysty i ostry. Czy ty też tego nie lubisz?

+0

To jest całkiem zły przykład, ponieważ obj.property = ... działa dobrze w Objective-C i nic nie robi. – gnasher729

+0

Nie mam na myśli Celu-C. Jest to po prostu ogólny przypadek dla większości języków programowania. Spróbuj tego na przykład w Lua. Wypadek! –

+0

To pytanie zostało zmienione. Kiedy odpowiedziałem na to pytanie, myślę, że w pytaniu nie wspomniano o zeru celu ani o porównaniu Swift z Objective-C. To pytanie musi zostać połączone lub zmienione. Stracił pierwotny zamiar. –

-2

W Objective-C można zdefiniować zmienną bez wartości. Jeśli chcesz użyć tej zmiennej przed przypisaniem wartości, otrzymasz niezdefiniowane zachowanie (które jest bardzo złe). Wręcz przeciwnie, szybka zapobiega scenariuszowi, w którym wartość obiektu jest nieznana.

+1

Od czasu wprowadzenia ARC kilka lat temu dowolny wskaźnik do obiektu Objective-C jest automatycznie inicjalizowany do zera. Bez niezdefiniowanego zachowania. Jeśli włączysz odpowiednie ustawienia kompilacji, kod nie zostanie skompilowany, jeśli spróbujesz użyć niezainicjowanej zmiennej. – gnasher729

2

Staje się "bezpieczny", ponieważ zmusza programistę do napisania bardziej wyraźnego kodu.

  • if let ... i guard składnia wyraźnie mówi „to zrobić tylko wtedy, gdy istnieją wartości tych zmiennych”.
  • Składnia powoduje awarię programu, jeśli zmienna to nil, gdy programista nie oczekiwał, że będzie to nil.

Natomiast sposób Objective-C jest od wykonywania połączeń do nil no-op może niech program nadal wykonywać do momentu rozpatrzenia nil jest nie do zaakceptowania. Typowym przykładem są zmienne nilNSString. Wiele wywołań funkcji API jest zadowolonych z nilNSString, z wyjątkiem sytuacji, gdy konstruujesz NSAttributedString (nie będzie akceptował parametru nilNSString i spowoduje awarię aplikacji). Dlatego gdy otrzymasz zmienną NSString, która niespodziewanie stanie się nil, może upłynąć trochę czasu, zanim aplikacja się zawiesi, ponieważ próbuje skonstruować przypisany ciąg o wartości nil.

Aby uzyskać pełniejszą ilustrację problemu, który usiłowano rozwiązać, należy wziąć pod uwagę this post back from 2010 by Daniel Jalkut. Zostało to napisane na długo przed Swift.

2

Ogólnie w programowaniu chcemy unikać zmiennych, które nie mają wartości (null lub nil), ponieważ ich używanie często powoduje niezdefiniowane zachowanie (wyjątki, błędy, awarie).

Na przykład często stosowaną praktyką jest, aby dla odwołań Array ustawić pustą tablicę zamiast nil. Na pustej tablicy możemy użyć wszystkich metod, np. Array. indexOf lub count. Używanie ich na nil może spowodować awarię.

Opcje pozwalają nam określić, że niektóre zmienne nigdy nie są puste, dlatego możemy z nich korzystać bezpiecznie, a kompilator sprawdza, czy nil nigdy nie jest do nich przypisany. Ponadto, kompilator wymusza na kliencie, że każda konwersja z opcji do nie-opcji jest jawna (w razie potrzeby zawsze sprawdzamy pod kątem nil).

Więc odpowiedź będzie, że OPCJE:

  1. Wymuszanie dobrych praktyk programistycznych.
  2. pozwolić na lepsze sprawdzanie kodu w czasie kompilacji

zapobiegając w ten sposób błędów programistycznych.

Należy również pamiętać, że zawsze należy unikać opcji, jeśli to możliwe. Największą zaletą opcji jest fakt, że większość zmiennych nie jest opcjami.

+0

Czy mógłbyś rozwinąć swoje ostatnie zdanie: "Największą zaletą opcji jest to, że większość zmiennych nie jest opcjami."? –

+0

@JoeHuang To całkiem proste. Jeśli wszystkie twoje zmienne są opcjami, wrócisz do świata bez opcji. Wszystko może być 'nil'. Moc opcji polega na ograniczeniu 'nil' do określonych bibliotek. – Sulthan

+0

Myślę, że jest więcej opcji przy rozważaniu programowania asynchronicznego. Nie rozumiem, jak zrobić większość zmiennych, a nie opcji. –

Powiązane problemy