字符串的模式匹配

时间:2017-09-19 20:47:03

标签: swift string pattern-matching

func swtiching (a: String, b: String){
    switch (a,b){
    case ("a", "b"): print("a and b")
    case (("a" || "c"), ("b" || "d")): print(" a or b and c or d")

    default: print("something else")
    }
}

如果我这样做,第二种情况会出现以下错误:

  

无法转换类型' String'的值预期的参数类型   '布尔'

修改

if "a" == "a" || "c"{
print("xyz")
}

这也会导致同样的错误。

2 个答案:

答案 0 :(得分:3)

这就是我要做的事情:

struct DisjunctiveMatcher<T: Equatable> {
    let desired: [T]
    func matches(candidate: T) -> Bool { return desired.contains(candidate) }
}

func ~= <T: Equatable>(pattern: DisjunctiveMatcher<T>, candidate: T) -> Bool {
    return pattern.matches(candidate: candidate)
}

func oneOf<T: Equatable>(_ elements: T...) -> DisjunctiveMatcher<T> {
    return DisjunctiveMatcher(desired: elements)
}


func swtichingExample(a: String, b: String) {
    switch (a, b) {
    case ("a", "b"): print("a and b")
    case (oneOf("a", "b"), oneOf("b", "d")): print(" a or b and c or d")

    default: print("something else")
    }
}

如果你真的想要达到你想要的语法,那也是可能的,但我强烈建议反对它,因为||的这种重载是相当的不直观,偏离了人们的期望。我只是指出它是可能的:

/// Starts a chain of strings, where lhs and rhs are used to
/// define a DisjunctiveMatcher<String>
func || (lhs: String, rhs: String) -> DisjunctiveMatcher<String> {
    return DisjunctiveMatcher(desired: [lhs, rhs])
}

/// Extends an existing chain of strings, where rhs is added
/// to the desired strings of las
func || (lhs: DisjunctiveMatcher<String>, rhs: String) -> DisjunctiveMatcher<String> {
    return DisjunctiveMatcher(desired: lhs.desired + [rhs])
}

func crazySwitchingExample(a: String, b: String) {
    switch (a, b) {
    case ("a", "b"): print("a and b")
    case (("a" || "c"), ("b" || "d")): print("Go home, you're drunk. ")

    default: print("something else")
    }
}

答案 1 :(得分:1)

使用元组模式,如果您想匹配a的不同组合的所有组合,其中一个是&#34; a&#34;或&#34; c&#34;并且b是&#34; b&#34;之一或者&#34; d&#34;,据我所知,如果你不重载模式匹配运算符(~+),你唯一的解决方案是明确写出所有可能的元组({ {1}}),即使对于2个值也非常麻烦。

我认为使用("a",b"),("a","d"),("c","b"),("c","d")语句并创建一个包含变量所有可能值的数组,然后调用if对于这种情况更容易解决。

[String].contains()