Ori*_*rds 6 pattern-matching swift swift4
我有一个带有几个字段的自定义结构,我想在swift switch语句中对它进行模式匹配,这样我就可以通过将一个字段与正则表达式进行比较来自定义匹配.
例如,鉴于这种结构:
struct MyStruct {
let header: String
let text: String
}
Run Code Online (Sandbox Code Playgroud)
我想像这样模式匹配:
switch(someInstance) {
case ("h1", "[a-z]+"): ...
case ("h1", "0-9+"): ...
}
Run Code Online (Sandbox Code Playgroud)
我尝试使用模式匹配函数使其工作如下:
func ~=(pattern: (String, String), value: MyStruct) -> Bool {
return value.header == pattern.0 && value.text.range(of: pattern.1, options: .regularExpression) != nil
}
Run Code Online (Sandbox Code Playgroud)
但是Xcode(9)无法使用此错误进行编译:
元组模式不能匹配非元组类型'MyStruct'的值
我能够达到的最好成绩如下:
struct MatchMyStruct {
let header: String
let regex: String
init(_ header: NSString, _ regex: String) {
self.header = header
self.regex = regex
}
}
func ~=(pattern: MatchMyStruct, value: MyStruct) -> Bool {
return value.header == pattern.header && value.text.range(of: pattern.regex, options: .regularExpression) != nil
}
Run Code Online (Sandbox Code Playgroud)
这让我模仿这样的匹配:
switch(someInstance) {
case MatchMyStruct("h1", "[a-z]+"): ...
case MatchMyStruct("h1", "0-9+"): ...
}
Run Code Online (Sandbox Code Playgroud)
虽然这是功能性的,但我更倾向于不必MatchMyStruct像这样明确包装器.
似乎swift有一些神奇的秘诀,用于与元组相匹配的模式.我能在这做什么吗?
您可以创建一个计算属性来返回一个元组:
struct MyStruct {
let header: String
let text: String
var tuple: (String, String) { return (header, text) }
}
Run Code Online (Sandbox Code Playgroud)
然后你可以switch根据tuple计算属性:
switch(someInstance.tuple) {
case ("h1", "[a-z]+"):
...
case ("h1", "0-9+"):
...
default:
...
}
Run Code Online (Sandbox Code Playgroud)
或者,如果您的目的是执行正则表达式匹配:
switch(someInstance.tuple) {
case ("h1", let string) where string.range(of: "^[a-z]+$", options: .regularExpression) != nil:
print("alphabetic")
case ("h1", let string) where string.range(of: "^[0-9]+$", options: .regularExpression) != nil:
print("numeric")
default:
print("other")
}
Run Code Online (Sandbox Code Playgroud)
或者,如果这太拗口了,您可以定义一些用于正则表达式模式匹配的字符串函数,例如:
extension String {
func isMatch(regex pattern: String) -> Bool {
return range(of: "^" + pattern + "$", options: .regularExpression) != nil
}
func contains(regex pattern: String) -> Bool {
return range(of: pattern, options: .regularExpression) != nil
}
}
Run Code Online (Sandbox Code Playgroud)
进而:
switch(someInstance.tuple) {
case ("h1", let string) where string.isMatch(regex: "[a-z]+"):
print("alphabetic")
case ("h1", let string) where string.isMatch(regex: "[0-9]+"):
print("numeric")
default:
print("other")
}
Run Code Online (Sandbox Code Playgroud)
或者按照您想要的方式执行此操作,但这只是为了说明如果您想要元组匹配,您可以定义计算属性来返回元组,然后在子句中执行您想要的任何操作where。
| 归档时间: |
|
| 查看次数: |
1027 次 |
| 最近记录: |