2016-09-20 2 views
2

Suche nach einem Doc-Verweis oder einem Namen oder einer Verknüpfung zu diesem bestimmten Verhalten, die der optionalen Bindung ähnelt, aber in diesem Teil der Dokumentation nicht behandelt wird.Swift Optionale und Gleichheitsoperator

ich einen optional mit dem == Operator testen kann, und Test sowohl gegen nil und seinen tatsächlichen Wert, ohne ein explizites Abwickeln zu tun:

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

Dies kompiliert und funktioniert, wie Sie es wollen würden, aber Was hier passiert ist, dass ich toggle! nicht explizit auspacken musste; die == hat es sicher für mich gemacht.

Es ist bequem, aber ich gestehe, ein wenig überrascht zu sein, als ich es bemerkte. Ist das nur ein Verhalten der Standard-Implementierung ==? Oder ist etwas anderes in der Sprache hier passiert? Danke für die Einsicht.

+2

Wenn Sie auf das '==' klicken, dann sehen Sie, dass es ein 'public func == (lhs: T ?, rechts: T?) -> Bool 'gibt, das zwei Optionals als akzeptiert Operanden. –

+0

In der Tat, aber warum sollte es? Ist das philosophisch im Sprachdesign? Oder nur eine Bequemlichkeit? Oder denke ich zu viel darüber nach? –

+3

Es ist Bequemlichkeit, denke ich. Die Vergleichsoperatoren, die Optionals verwenden, wurden in Swift 3 entfernt: https://github.com/apple/swift-evolution/blob/master/proposals/0121-remove-optional-comparison-operators.md. Aber die Gleichheitsoperatoren blieben: * "Varianten von == und! =, Die optionale Operanden akzeptieren, sind immer noch nützlich, und ihre Ergebnisse sind nicht überraschend, also werden sie bleiben." * –

Antwort

5

Swift hat eine Gleichheits-Operator nimmt zwei optionals Werte (eines gleichzusetzen Basistyp):

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

Die Implementierung kann auf Optional.swift finden:

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

und es tut, was würde man expect: Die Operanden sind gleich, wenn sie beide nil sind, oder wenn sie beide nicht nil sind und die unverpackten Werte gleich sind.

Ähnliche Vergleichsoperatoren < usw. unter optionals haben in Swift 3 entfernt worden ist, vergleichen SE-0121 Remove Optional Comparison Operators:

Entfernen Sie die Versionen von <, < =,> und> = welche akzeptieren optionale Operanden.

Varianten von == und! =, Die optionale Operanden akzeptieren, sind immer noch nützlich, und ihre Ergebnisse sind nicht überraschend, so dass sie bleiben werden.

So funktioniert das wie erwartet:

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

Aber wie matt darauf hingewiesen, kann dies nicht mit implizit ausgepackt optionals getan werden, hier der linke Operand ausgepackt werden:

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

Warnung: Versuchen Sie dies nicht mit einem implizit unverpackten Optional. Schreckliche Dinge (tm) können passieren. – matt

Verwandte Themen