Как необязательное связывание используется в swift?

В быстрой версии для управления потоком допустим следующий синтаксис

if let constantName = someOptional {
    statements
}

В этом контексте какова семантика контекста значения истинности?

Разрешено ли цепочка выражений (например, ниже)?

if let constantName = someOptional &&  constantName2 = someOptional2 {
    statements
}

Если это так, происходит ли короткое замыкание в булевом выражении?

Ответ 1

Сначала проверяется someOptional, чтобы узнать, имеет ли он нуль или имеет данные. Если он равен нулю, оператор if просто не выполняется. Если есть данные, данные распаковываются и присваиваются constantName для области действия if-statement. Затем выполняется код внутри фигурных скобок.

if let constantName = someOptional {
    statements
}

Невозможно связать эту функциональность в одном if-statement. let constantName = someOptional напрямую не вычисляется в булево. Лучше всего думать о "если пусть" как о специальном ключевом слове.

Ответ 2

В Swift 1.2 и 2.1 вы можете сделать это:

if let constantName = someOptional, constantName2 = someOptional2 {
    // statements
}

Ответ 3

Вы не можете связать необязательное связывание следующим образом:

if let constantName = someOptional && constantName = someOptional2 {}

но в Swift 1.2 вы можете записать это:

if let constantName = someOptional, constantName = someOptional2 {}

Что здесь происходит?

Опционы являются их собственным типом и являются быстрым способом обеспечения проверки времени компиляции для nil. Когда вы вводите var potentialValue : Int?, вы не используете какой-либо специальный Int, вы используете необязательный тип, который по сути является пустым перечислением. Вот почему вам часто приходится разворачивать опцию с помощью !, так как это позволяет вам получить доступ к тому, что внутри (если есть что-то внутри). Если опция не содержит значения (т.е. Перечисление пусто), то оно имеет значение None. Если опция не пустая, то она имеет значение Some и связанное значение любого типа, который вы используете, поэтому в этом случае Int.

Это:

if (someOptional != nil){
    let constantName = someOptional!
}

то же самое, что и при использовании:

if let constantName = someOptional {}

который называется необязательным связыванием. Вы заметите, что вторая версия здесь немного читаема, и вам не нужно явно разворачивать опцию, используя !.

Он вычисляет значение true, когда необязательное значение Some, а не None - другими словами, когда необязательный параметр не равен нулю. (Обратите внимание, что вы по-прежнему можете проверить nil, если хотите, а также изменить необязательное значение на None, написав someOptional = nil.

Что-то еще, о чем не упоминалось, это то, что вы можете использовать ?? (называемый nil coalescing operator), чтобы дать необязательный значение по умолчанию, если оно отсутствует. Например:

let constantName = someOptional ?? 100

Здесь someOptional будет развернуто, если оно имеет значение, но если оно не используется, вместо этого используется значение 100.

Мне полезно помнить, что в Swift есть свои собственные опции. Они не являются причудливой версией того типа, о котором вы говорите.

Ответ 4

Сначала someOptional проверяется, есть ли его nil. Если его нет, то constantName присваивается развернутому значению someOptional. Если его nil, он переходит в оператор else.

Это означает, что даже если someOptional является Bool?, которому присваивается false, он по-прежнему будет входить в первый блок, а не в else.

Видео Intermediate Swift переходит в большую глубину по этой теме в течение первых 15 минут!

Ответ 5

Подумайте об этом так: Необязательный - это просто Enum со связанным значением.

enum OptionalValue<T> {
    case None
    case Some(T)
}

Когда вы назначаете опцию, под капотом используется значение .Some enum со связанным значением, которое вы дали. Если вы присвоите ему значение nil, оно получит значение None, без соответствующего значения.

if let constantName = someOptional {}

Делает ли if на перечислении. Если это. Некоторое, то константе присваивается связанное значение, и блок выполняется. В противном случае ничего не происходит.

Ответ 6

Необязательная привязка

Swift 2

   if let constantName = someOptional, constantName2 = someOptional2 {
                // your statement goes here .....
                print(constantName)
                print(constantName2)
            }

swift 3

if let constantName = someOptional, let constantName2 = someOptional2 {
            // your statement goes here .....
            print(constantName)
            print(constantName2)
        }

Ответ 7

if let constantName = someOptional {
    statements
}

В основном то, что здесь происходит, заключается в том, что если someOptional имеет значение, отличное от nil, constantName присваивается someOptional значение для объема этого if-утверждения.

В терминах семантики порядок выполнения событий: A) someOptional проверяется на nil, B), а затем ему присваивается константаName, а затем, наконец, выполняются инструкции C в if-блоке.

Обычно значение делать что-то вроде этого состоит в том, что оно предотвращает сбой приложения, если у вас в противном случае значение nil. Стоит отметить, что nil в Swift, если отличается от Objective-C, потому что он более мощный, чем просто указатель.

Кроме того, если someOptional - это Bool, который является False, обратите внимание, что он все равно выполнит этот if-block, потому что он не проверяет true/false, а скорее наличие/отсутствие значения. Наличие False делает if-block true.

Ответ 8

Из Apple Doc

Дополнительное связывание

Чтобы условно связать завернутое значение экземпляра Option с новой переменной, используйте одну из необязательных структур управления связыванием, в том числе, пусть let, guard let и switch.

if let starPath = imagePaths["star"] {
    print("The star image is at '\(starPath)'")
} else {
    print("Couldn't find the star image")
}

Необязательная цепочка

Чтобы безопасно обращаться к свойствам и методам обернутого экземпляра, используйте постсинтетический необязательный оператор цепочки (postfix?). В следующем примере используется необязательная цепочка для доступа к методу hasSuffix (_:) на String? экземпляр.

        if let isPNG =imagePaths["star"]?.hasSuffix(".png") {
            print("The star image is in PNG format")
        }
        // Prints "The star image is in PNG format"