2016-05-17 8 views
4

kann ich if let Konstrukt verwenden optionals auszupacken, wie folgt aus:Kann ich eine Klasse erstellen, die an "if let" beteiligt ist, wie das Optional ausführt?

if let x = someOptional { 
    // x represents the value of someOptional, and is known to be non-nil 
} 

Neben dem Abwickeln tun, Swift-Compiler kennt das let x = someOptional Konstrukt als logischer Wert zu behandeln.

Ist die Logik für Optional in den Compiler selbst integriert, oder ist es möglich, meine eigene Klasse mit demselben Verhalten zu definieren?

Mit anderen Worten, ich kann schreiben etwas wie folgt aus:

class MyLogical : SomeProtocolForSwiftToKnowHowToTreatMyClassAsBool { 
    ... 
    var boolValue : Bool { 
     return ... // true or false, depending on the state of my object 
    } 
} 

und haben Swift behandeln es wie ein logischer Wert, die ich innerhalb eines if Zustand setzen kann, mit oder ohne let?

if let x = getMyLogical() { 
    assert(x.boolValue) // boolValue must evaluate to true to get here 
} 

Hinweis: Ich erinnere mich, es in einer früheren Version von Swift ein LogicalValue Protokoll zu sein, und Optional verwendet, um dieses Protokoll zu entsprechen. LogicalValue ist jetzt weg, und es gibt keinen Ersatz (BooleanType hat die boolValue Eigenschaft jetzt, aber Apple entmutigt Konformität mit dem BooleanType Protokoll, es sei denn Ihre Klasse stellt einen einfachen booleschen Wert dar).

+1

"und Swift behandelt es wie einen logischen Wert, den ich in eine if-Bedingung setzen kann" Aber Sie scheinen Äpfel mit Orangen zu verwechseln, nein, jetzt ist es nicht klar, was Sie tun wollen. In 'if let x = getMyLogical()' müsste 'getMyLogical()' etwas ergeben, das "nil" sein kann und, falls nicht, nicht ausgepackt werden kann - kein logischer Wert. Die "Logik" in "Wenn lassen" kommt später. Willst du ein Boolean-ähnliches Ding oder ein Optional-ähnliches Ding? – matt

+0

@matt Stellt 'NilLiteralConvertible' nicht etwas dar, auf das ich' nil' setzen kann, nicht etwas, das ich zurück in 'nil' konvertieren kann? Es würde mir nichts ausmachen, für Dinge, die ich außerhalb meiner 'if'-Aussage behalten möchte,' 'nil'' zurück zu geben, um" falsch "zurück zu geben. Im Grunde bin ich auf der Suche nach einer Möglichkeit, benutzerdefinierte Logik in die Funktionalität von 'if' zu integrieren - ähnlich wie ich es in C++ machen kann, indem ich einen impliziten Operator für die Konvertierung zu' bool' zur Verfügung stelle. – dasblinkenlight

+0

Haben Sie sich die Implementierung der Option '' im Swift-Modul angeschaut? Willst du so etwas nachmachen? – JAL

Antwort

3

Swifts leistungsstarkes Pattern-Matching-System macht es möglich. Das case let... Muster nicht viel von dem, was Sie vorschlagen:

if case let x = getMyLogical() where x.boolValue { 
    assert(x.boolValue) // boolValue must evaluate to true to get here 
} 

Es arbeitet mit guard Aussagen zu:

guard case let x = getMyLogical() where x.boolValue else { fatalError() } 

assert(x.boolValue) // boolValue must evaluate to true to get here 

Mit anderen Worten, die case let... Syntax bedingt verwendet werden kann, um einen beliebigen Wert zu einem beliebigen Namen zu binden für Verwenden Sie in einem if Block oder nach einer guard Anweisung.

Und ich der Vollständigkeit halber nehme an, es funktioniert in einem switch Block auch:

switch getMyLogical() { 
case let x where x.boolValue: 
    assert(x.boolValue) // boolValue must evaluate to true to get here 
default: 
    break 
} 

Und als logische Test für eine Schleife:

while case let x = getMyLogical() where x.boolValue { 
    assert(x.boolValue) // boolValue must evaluate to true to get here 
} 

Für eine lange Zeit dachte ich switch Aussagen waren die einzigen Orte, die man verwenden konnte case let... Aber sie können auch an anderen Orten verwendet werden.

Ich füge eine letzte Notiz hinzu. Das case let... Muster kann auch verwendet werden, optionals auszuzupacken:

let num: Int? = 42 
if case let x? = num { 
    print(x) 
} 

Die if let... Syntax für Abwickeln optionals ein Sonderfall der allgemeinen case let... Pattern-Matching-Syntax zu sein scheint, ein zusätzliches Bit syntaktischen Zucker optionals zu machen noch einfacher arbeiten mit, aber nicht grundlegend anders als die allgemeinere case let... Funktionalität.

+0

Dies ist sogar noch besser, da der Aufruf von 'x.boolValue' explizit erfolgt. Vielen Dank! – dasblinkenlight