Подтвердить что ты не робот

Что означает восклицательный знак в собственности на языке Swift?

Существует три способа объявления свойства в Swift:

var optStr: String?
var normStr: String = "normStr"
var exactStr: String!

Первый - это свойство с типом optional, тип, который может содержать либо nil, либо String в нашем случае. Второй - это свойство, в котором всегда содержит строку. Он должен быть инициализирован в init или в объявлении.

Но как насчет третьего пути?

var exactStr: String!

Я сделал несколько экспериментов на игровой площадке, и оказалось, что функция, которая принимает type?, может принимать как аргументы type, type?, так и type! в качестве аргумента:

var optStr: String?
var normStr: String
var forcedStr: String!

func printStr(str: String?) {
    println("str: \(str)")
}

printStr(optStr) //prints: "str: nil"
//printStr(normStr) //doesn't compile as not initialized
printStr(forcedStr) //prints: "str: nil"

optStr = "optStr"; normStr = "normStr"; forcedStr = "forcedStr"

printStr(optStr) //prints "str: optStr"
printStr(normStr) //prints "str: normStr"
printStr(forcedStr) //prints "str: forcedStr"

Так почему и когда я должен использовать type!?

Обновление: это не дубликат Что означает восклицательный знак на языке Swift?. Я не спрашиваю об открытии переменной: я спрашиваю о declaring свойстве с восклицательным знаком (type!).

4b9b3361

Ответ 1

Это переменная типа "неявно-развернутая необязательная строка". По сути, каждый доступ implicitStr обрабатывается так, как если бы он был написан implicitStr! (таким образом, разворачивая значение).

Это, конечно, вызовет сбой, если значение равно нулю. Вы все еще можете проверить неявное необязательное значение через if implicitStr != nil или использовать его в необязательной цепочке как var foo = implicitStr?.uppercaseString. Таким образом, вы все равно можете использовать его так же безопасно, как и обычный вариант; он просто смещен к случаю, когда значение не равно нулю.

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

Кроме того, поскольку методы Objective-C могут возвращать как типы nil, так и типы объектов, их возвращаемые значения нельзя смоделировать как необязательные. Чтобы избежать необходимости либерального использования принудительной разворачивания при работе с API Cocoa, однако, параметры и возвращаемые типы API-интерфейсов Cocoa обычно представляются как неявно-развернутые опции.