[swift-users] Optionals in switch statements

Loïc Lecrenier loiclecrenier at icloud.com
Wed Jun 29 05:53:19 CDT 2016


Hi Matteo,

I would write it like that:

func switch_updateFileFrom(from : String?, to: String?)
{
    switch(from, to) {

    case (nil, nil):
        print("Nothing to do, both are nil")

    case let (x?, y?) where x == y:
        print("Nothing to do, both are non-nil and equal")

    case let (x?, y?):
        print("Renaming \(x) to \(y)")

    case let (x?, nil):
        print("Deleting \(x)")

    case let (nil, y?):
        print("Creating \(y)")
    }
}

“x?” is syntactic sugar for “.Some(x)"
“nil” is a literal equivalent to “.None” (in this case)

Loïc

> On Jun 29, 2016, at 12:42 PM, Matteo via swift-users <swift-users at swift.org> wrote:
> 
> I’m trying to make the best use of swift’s switch statement while converting some old code from obj-c.
> 
> Imagine a method that takes two optional strings representing file names:
> 
> func updateFileFrom(from : String?, to: String?)
> 
> If both strings are nil, then it does nothing.
> If both are non nil AND are equal it also does nothing
> If both are non-nil and not equal it renames the file
> If from is not nil, but to is nil, it deletes the file.
> If from is nil, but to is not-nil it creates a file.
> 
> Here is my original implementation as a straight conversion using only if:
> 
> func ifs_updateFileFrom(from : String?, to: String?)
> {
>    if from == nil && to == nil {
>        print("Nothing to do, both are nil")
>    } else if from != nil && to != nil {
>        if from == to {
>            print("Nothing to do, both are non-nil and equal")
>        } else {
>            print("Renaming \(from!) to \(to!)")
>        }
>    } else if to == nil {
>        print("Deleting \(from!)")
>    } else {
>        print("Creating \(to!)")
>    }
> }
> 
> So I’ve had a go at using a switch statement to make it more readable:
> 
> func switch_updateFileFrom(from : String?, to: String?)
> {
>    switch (from, to) {
>    case (.None, .None):
>        print("Nothing to do, both are nil")
>    case (.Some, .Some) where from == to:
>        print("Nothing to do, both are non-nil and equal")
>    case (.Some, .Some):
>        print("Renaming \(from!) to \(to!)")
>    case (.Some, .None):
>        print("Deleting \(from!)")
>    case (.None, .Some):
>        print("Creating \(to!)")
>    }
> }
> 
> It seems reasonable to me and clearer, but I don’t really like accessing the from and to variables within it, it just doesn’t feel right compared to ‘normal’ switch statement
> 
> i.e consider this example from the swift book:
> 
> let anotherPoint = (2, 0)
> 
> switch anotherPoint {
> case (let x, 0):
>    print("on x-axis with x value of \(x)")
> case (0, let y):
>    print("on y-axis with y value of \(y)")
> case let (x, y):
>    print("Somewhere else at (\(x), \(y))")
> }
> 
> The switch statement is entirely self-referential with regard to the internally bound values of x and y, it has no need to access anotherPoint directly.
> 
> Is there a way to write my switch-based method that does not access from and to directly, but is also as clear?
> 
> Thanks
> 
> 
> 
> _______________________________________________
> swift-users mailing list
> swift-users at swift.org
> https://lists.swift.org/mailman/listinfo/swift-users



More information about the swift-users mailing list