2016-09-20 3 views
2

Ищете ссылку на документ или имя или ссылку на это поведение, подобное факультативной привязке, но не обсуждаются в этой части документов.Быстрые опционы и оператор равенства

я могу проверить опциональный с оператором == и испытание как против nil и его реальной стоимости, не делая какие-либо конкретные развёртки:

var toggle: Bool? = nil 
if (toggle == true || toggle == nil) { 
    // do something 
} 

Это компилирует и работает, как вы хотите, но что произошло здесь, так что мне не пришлось явно разворачивать toggle!; == благополучно сделал это для меня.

Это удобно, но я признаюсь, что немного удивлен, когда заметил это. Является ли это просто поведением реализации по умолчанию ==? Или что-то еще на этом языке происходит здесь? Спасибо за понимание.

+2

Если вы нажмете команду на '==', вы увидите, что существует 'public func == (lhs: T ?, rhs: T?) -> Bool', который принимает два дополнительных варианта: операнды. –

+0

Действительно, но зачем это нужно? Является ли это философским в языковом дизайне? Или просто удобство? Или я слишком много думаю об этом? –

+3

Удобство, думаю. Операторы сравнения, берущие опции, которые удалены в Swift 3: https://github.com/apple/swift-evolution/blob/master/proposals/0121-remove-optional-comparison-operators.md. Но операторы равенства остались: * «Варианты == и! =, Которые принимают необязательные операнды, по-прежнему полезны, и их результаты неудивительны, поэтому они останутся». * –

ответ

5

Swift имеет оператор равенства принимает два УСТРОЙСТВА значения (из Equatable базового типа):

public func ==<T : Equatable>(lhs: T?, rhs: T?) -> Bool 

Реализация можно найти на Optional.swift:

public func == <T: Equatable>(lhs: T?, rhs: T?) -> Bool { 
    switch (lhs, rhs) { 
    case let (l?, r?): 
    return l == r 
    case (nil, nil): 
    return true 
    default: 
    return false 
    } 
} 

и делает то, что один будет expect: Операнды равны, если они равны nil, или если они оба не равны nil, а развернутые значения равны.

Подобных операторы сравнения < и т.д. принимая OPTIONALS был снятого в Swift 3, сравнить SE-0121 Remove Optional Comparison Operators:

Удалить версии <, < =,> и> =, которые принимают дополнительные операнды.

Варианты == и! =, Которые принимают необязательные операнды, по-прежнему полезны, и их результаты неудивительны, поэтому они останутся.

Так что это работает, как ожидалось:

let b: Bool? = nil 
print(b == true) // prints "false" 

Но, как матовые отметил, что это не может быть сделано с неявным разворачивал УСТРОЙСТВО, здесь левый операнд будет распакованным:

let b: Bool! = nil 
print(b == true) // crashes 
+1

Предупреждение: не пытайтесь это с помощью неявно развернутого варианта. Ужасные вещи (tm) могут случиться. – matt