Abiodun Abiodun - 5 months ago 27
Swift Question

OptionSetType protocol Swift

What’s the purpose of Swift’s

OptionSetType
protocol, and how does it differ from just leveraging
Set
to get those
SetAlgebraType
methods?

Answer

I'll answer from the practical perspective when using OptionSetType. To me, the purpose of OptionSetType is to remove all the bit manipulation in C / ObjC.

Consider an example when you have a function that draws the borders of a rectangle. The user can ask it to draw between 0 and 4 borders.

Here's the 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])

And 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 |= BorderTypeLeft;

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

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

C is shorter but, at a glance, who can tell what this line does?

border &= ~BorderTypeBottom;

While this makes instant sense:

var border2 = border
border2.remove(.Bottom)

It fits into Swift's objective of being an expressive, easy to learn language, compare to the spartan philosophy of C.