Szybkie, zmienne dekoracje z „?” (znak zapytania) i „!” (wykrzyknik)

106

Rozumiem, że w Swift wszystkie zmienne muszą mieć przypisaną wartość i że za pomocą opcji opcjonalnych możemy ustawić zmienną, która ma być ustawiona nilpoczątkowo.

Nie rozumiem, co robi ustawienie zmiennej na a !, ponieważ miałem wrażenie, że to „odpakowuje” wartość z opcjonalnej. Pomyślałem, że robiąc to, gwarantujesz, że ta zmienna ma wartość do rozwinięcia, dlatego w IBActions i takich, jak widzisz, jest używana.

Krótko mówiąc, do jakiej zmiennej jest inicjowana, gdy robisz coś takiego:

var aShape : CAShapeLayer!

A dlaczego / kiedy miałbym to zrobić?

Jason Renaldo
źródło
Zrobiłbyś to, aby stwierdzić, że zmienna jest nt zerowa po sprawdzeniu tego faktu.
Matthias
Nie sądzę, aby to oznaczało jako duplikat. „Co jest opcjonalne?” to nie to samo pytanie co „Jaka jest różnica między tymi dwoma typami opcji?” co jest
właściwie
@Jiaaro nawet w tym przypadku jest już mnóstwo pytań dotyczących opcji, niejawnie rozpakowanych opcji i tym podobnych. Możesz również odnieść się do tego: stackoverflow.com/questions/24272781/…
Jack
@JackWu Ok, ale jestem prawie pewien, że to pytanie nie zostało powtórzone, gdy zostało zadane. (na przykład zadano to cały tydzień przed twoim przykładem)
Jiaaro
@Jiaaro Masz rację, nie zauważyłem, że to było starsze .. może zamiast tego należy oznaczyć inny jako duplikat tego ..
Jack

Odpowiedzi:

145

W deklaracji typu !jest podobny do ?. Obie są opcjonalne, ale !jest to opcjaniejawnie rozpakowana” , co oznacza, że ​​nie trzeba jej rozpakowywać, aby uzyskać dostęp do wartości (ale nadal może być zero).

Jest to w zasadzie zachowanie, które już mieliśmy w celu-c. Wartość może wynosić zero i musisz to sprawdzić, ale możesz również uzyskać bezpośredni dostęp do wartości, tak jakby nie była opcjonalna (z tą ważną różnicą, że jeśli nie sprawdzisz, czy nie ma zera, otrzymasz błąd wykonania)

// Cannot be nil
var x: Int = 1

// The type here is not "Int", it's "Optional Int"
var y: Int? = 2

// The type here is "Implicitly Unwrapped Optional Int"
var z: Int! = 3

Stosowanie:

// you can add x and z
x + z == 4

// ...but not x and y, because y needs to be unwrapped
x + y // error

// to add x and y you need to do:
x + y!

// but you *should* do this:
if let y_val = y {
    x + y_val
}
Jiaaro
źródło
7
Niejawnie rozpakowane opcje są opisane w trafnie nazwanej sekcji rozpoczynającej się na stronie 56 języka Swift Programming Language .
Caleb
@Caleb Dodałem link do odpowiedniej sekcji dokumentów online, w których wspomniałem niejawnie rozpakowane
opcje
Świetna informacja, dzięki. Ogólnie rzecz biorąc, kochanie bezpieczeństwa, które do tej pory wymusza na nas Swift, powinno powodować znacznie mniej błędów :).
Jason Renaldo
@Jiaaro: Bardzo dziękuję za udostępnienie. To sprawia, że ​​użytkownik doskonale rozumie powyższy przykład. !! :)
Esha
3
Myślę, że zdanie „ To jest w zasadzie zachowanie, które już mieliśmy w celu-c ” może być mylące. W celu-c można uzyskać dostęp do nilwartości i faktycznie z nią „pracować”, przy szybkim dostępie do niejawnie rozpakowanego elementu opcjonalnego, gdy jest on zerowy, zgłosi wyjątek czasu wykonania.
Sascha Wolf