2016-06-29 9 views
1

Was ist der Zweck von Swifts OptionSetType Protokoll, und wie unterscheidet es sich von nur Set zu nutzen, um diese SetAlgebraType Methoden zu bekommen?OptionSetType Protokoll Swift

Antwort

3

Ich werde aus der praktischen Perspektive beantworten, wenn Sie OptionSetType verwenden. Für mich ist der Zweck von OptionSetType, alle Bit-Manipulation in C/ObjC zu entfernen.

Betrachten Sie ein Beispiel, wenn Sie eine Funktion haben, die die Grenzen eines Rechtecks ​​zeichnet. Der Benutzer kann ihn bitten, zwischen 0 und 4 Grenzen zu zeichnen.

Hier ist der Code in Swift:

struct BorderType: OptionSetType { 
    let rawValue: Int 
    init (rawValue: Int) { self.rawValue = rawValue } 

    static let Top = BorderType(rawValue: 1 << 0) 
    static let Right = BorderType(rawValue: 1 << 1) 
    static let Bottom = BorderType(rawValue: 1 << 2) 
    static let Left = BorderType(rawValue: 1 << 3) 
} 

func drawBorder(border: BorderType) { 
    // Did the user ask for a Left border? 
    if border.contains(.Left) { ... } 

    // Did the user ask for both Top and Bottom borders? 
    if border.contains([.Top, .Bottom]) { ... } 

    // Add a Right border even if the user didn't ask for it 
    var border1 = border 
    border1.insert(.Right) 

    // Remove the Bottom border, always 
    var border2 = border 
    border2.remove(.Bottom) 
} 

drawBorder([.Top, .Bottom]) 

Und in C:

typedef enum { 
    BorderTypeTop = 1 << 0, 
    BorderTypeRight = 1 << 1, 
    BorderTypeBottom = 1 << 2, 
    BorderTypeLeft = 1 << 3 
} BorderType; 

void drawBorder(BorderType border) { 
    // Did the user ask for a Left border? 
    if (border & BorderTypeLeft) { ... } 

    // Did the user ask for both Top and Bottom borders? 
    if ((border & BorderTypeTop) && (border & BorderTypeBottom)) { ... } 

    // Add a Right border even if the user didn't ask for it 
    border |= BorderTypeRight; 

    // Remove the Bottom border, always 
    border &= ~BorderTypeBottom; 
} 

int main (int argc, char const *argv[]) 
{ 
    drawBorder(BorderTypeTop | BorderTypeBottom); 
    return 0; 
} 

C kürzer ist aber, auf einen Blick, wer kann sagen, was diese Zeile tut?

border &= ~BorderTypeBottom; 

Während macht diesen Augenblick Sinn:

var border2 = border 
border2.remove(.Bottom) 

Er paßt in Swifts Ziel, einen ausdruck sein, einfache Sprache zu lernen, zu vergleichen, zu der spartanischen Philosophie von C.

2

OptionSetType können Sie Ihre Klasse SetAlgebraType konform zu machen, ohne etwas Implementierung, unter der Annahme, dass Ihre Klasse ist RawRepresentable und seine rohe Darstellung ist BitwiseOperationsType. Dazu werden Standardimplementierungen für nine methods von SetAlgebraType bereitgestellt.

Der Hauptunterschied gegenüber der Nutzung Set ist, dass Sie nichts für eine gute Anzahl von Typen schreiben müssen, z. integrierte Typen. Alles, was Sie tun müssen, ist, Ihren Rohdarstellungstyp mit OptionSetType konform zu machen, und Sie erhalten alle Implementierungen kostenlos.

2

Es unterscheidet mich von ein Set in dem es ist nicht ein Set. Es ist eine Objective-C-Enumeration, deren Werte Bitmasken sind. Die Idee ist, Ihnen eine Möglichkeit zu geben, ein solches Enum in Swift so zu importieren, dass Sie es mit Set-ähnlicher Bequemlichkeit und Sicherheit manipulieren können, aber in Wirklichkeit bilden Sie eine ganze Zahl mit bitweisem und bitweisem oder. In Objective-C müssten Sie die Ganzzahl direkt konstruieren, indem Sie den bitwise-or-Operator verwenden. Aber Swift rettet dich davor, das tun zu müssen.

So Sie könnte sagen:

let val = 
    UIViewAnimationOptions.Autoreverse.rawValue | 
    UIViewAnimationOptions.Repeat.rawValue 
let opts = UIViewAnimationOptions(rawValue: val) 

... und in Objective-C, würden Sie das tun müssen, in der Tat. Aber Swift lässt Sie stattdessen sagen:

var opts = UIViewAnimationOptions.Autoreverse 
opts.insert(.Repeat) 
Verwandte Themen