Swift 2.2中的自定义模式匹配无法按预期工作

时间:2016-03-31 21:09:14

标签: ios swift swift2 switch-statement pattern-matching

按照优秀博客文章:https://appventure.me/2015/08/20/swift-pattern-matching-in-detail/#sec-3-7我尝试过自定义模式匹配。让我们定义一个代表两种字符串的enum

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

接下来,String扩展程序能够告诉字符串是否以LineType的一个或另一个值开头:

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

然后是自定义模式匹配函数,检查字符串是否属于给定类型:

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

最后,让我们用这个例子测试它:

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")
}

所以如果有人能告诉我我做错了什么......

提前致谢。

2 个答案:

答案 0 :(得分:2)

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
 */

仍然,尝试重新安排它......

它看起来很糟糕,但这可以正常运作

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
 */

这也应该有用

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

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

答案 1 :(得分:0)

是的,除了使用.rawValue之外没有其他解决方案。但是你已经知道如何做到这一点。

我在操场上测试了这个(使用Xcode 7.3),我可以确认这不起作用。向所涉及的函数添加public修饰符也没有帮助。我建议在Apple Bug Reporter提交错误报告,或者更好,Swift Bug Reporter(由@OleBegemann建议)。