Быстрые переменные украшения с помощью «?» (вопросительный знак) и «!» (восклицательный знак)

107

Я понимаю, что в Swift все переменные должны быть установлены со значением, и что, используя дополнительные параметры, мы можем установить переменную, которая будет установлена nilизначально.

Я не понимаю, что происходит при установке переменной с помощью !, потому что у меня создалось впечатление, что это "разворачивает" значение из необязательного. Я думал, что таким образом вы гарантируете, что в этой переменной есть значение, которое нужно развернуть, поэтому в IBActions и т. Д. Вы видите, что оно используется.

Проще говоря, какая переменная инициализируется, когда вы делаете что-то вроде этого:

var aShape : CAShapeLayer!

И зачем / когда мне это делать?

Джейсон Ренальдо
источник
Вы должны сделать это, чтобы сказать, что переменная nt nil после того, как вы проверите этот факт.
Матиас
Не думаю, что это следует отмечать как дубликат. "Что является необязательным?" это не то же самое, что вопрос «В чем разница между двумя типами опционалов?» что в значительной степени то, что это за вопрос
Jiaaro
@Jiaaro, даже в этом случае уже есть масса вопросов относительно опций, неявно развернутых опций и тому подобного. Вы также можете обратиться к этому: stackoverflow.com/questions/24272781/…
Джек
@JackWu Хорошо, но я почти уверен, что этот вопрос не повторялся, когда его задавали. (например, его спросили за целую неделю до вашего примера)
Jiaaro
@Jiaaro Вы хорошо заметили, я не заметил, что это было старше ... может быть, вместо этого следует пометить другой как дубликат этого ...
Джек

Ответы:

145

В объявлении типа объект !похож на ?. Оба являются необязательными, но это необязательный параметр !« неявно развернутый» , что означает, что вам не нужно развертывать его для доступа к значению (но оно все равно может быть нулевым).

В основном это поведение, которое мы уже имели в objective-c. Значение может быть нулевым, и вы должны его проверить, но вы также можете просто получить доступ к значению напрямую, как если бы оно не было необязательным (с той важной разницей, что если вы не проверяете ноль, вы получите ошибка выполнения)

// 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

Использование:

// 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
источник
7
Неявно развернутые опции описаны в правильно названном разделе, начинающемся на стр. 56 языка программирования Swift .
Калеб
@Caleb Я добавил ссылку на соответствующий раздел онлайн-документации, где я упомянул неявно развернутые опции :)
Jiaaro
Отличная информация, спасибо. Вообще, если мы любим безопасность, которую Swift навязывает нам до сих пор, должно появиться намного меньше ошибок :).
Джейсон Ренальдо
@Jiaaro: Большое спасибо за то, что поделились. Это заставляет пользователя прекрасно понять приведенный выше пример. !! :)
Еша
3
Я думаю, что предложение « Это в основном то поведение, которое мы уже имели в объекте-c », может сбивать с толку. В objective-c можно получить доступ к nilзначению и фактически «работать» с ним, при быстром доступе к неявно развернутому необязательному элементу, в то время как он nil вызовет исключение времени выполнения.
Саша Вольф