Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Custom pattern matching in Swift 2.2 not working as expected

Following the excellent blog post here: https://appventure.me/2015/08/20/swift-pattern-matching-in-detail/#sec-3-7 I've tried custom pattern matching. Let's define an enum representing two kinds of strings:

enum LineType : String {
    case Event = "event:"
    case Data = "data:"
}

Next, a String extension capable of telling if a string starts with one or the other value of the LineType:

extension String {
    func isOfType(type: LineType) -> Bool {
        return self.hasPrefix(type.rawValue)
    }
}

Then the custom pattern matching function, checking if a string is of a given type:

func ~= (pattern: LineType, value: String) -> Bool {
    return value.isOfType(pattern)
}

Finally, let's test it with this example:

let testLine = "event:yada-yada-yada"

switch testLine {
case _ where testLine.characters.count == 0:
    print("Empty")
case LineType.Event: // <--- Causes the error Enum case 'Event' is not a member of type 'String'
    print("Event")
case LineType.Data: // <--- Causes the error Enum case 'Data' is not a member of type 'String'
    print("Data")
default:
    print("Unknown Type")
}

So if someone can tell me what I do wrong...

Thanks in advance.

like image 655
Zaphod Avatar asked Mar 31 '16 21:03

Zaphod


1 Answers

switch testLine {
case _ where testLine.characters.count == 0:
    print("Empty")
case _ where testLine.isOfType(.Event): print("Event")
case _ where testLine.isOfType(.Data):  print("Data")
default: print("Unknown Type")
}

/* prints
 Event
 */

still, try to rearrange it ...

it looks terrible, but this works, as expected

enum LineType : String {
    case Event = "event:"
    case Data = "data:"
}
func ~= (pattern: LineType, value: String) -> Bool {
    return value.hasPrefix(pattern.rawValue)
}


let testLine = "event:yada-yada-yada"
let e = LineType.Event
let d = LineType.Data
switch testLine {
case let s where s.characters.count == 0: print("Empty")
case e: print("Event")
case d: print("Data")
default: print("Unknown Type")
}
/* prints
 Event
 */

this should also work

...
case { return LineType.Event }(): print("Event")
...

or

...
case { LineType.Event }(): print("Event")
...
like image 198
user3441734 Avatar answered Oct 12 '22 23:10

user3441734