Swift重载运算符在switch-case中的模式匹配

神奇的Swift

swift的switch-case语句可以非常灵活的进行匹配,每个case段可以对应一个或多个匹配项,这比其他语言都要好用。比如苹果官方文档中列举了一个例子:

for thing in things {
    switch thing {
    case 0 as Int:
        print("zero as an Int")
    case 0 as Double:
        print("zero as a Double")
    case let someInt as Int:
        print("an integer value of \(someInt)")
    case let someDouble as Double where someDouble > 0:
        print("a positive double value of \(someDouble)")
    case is Double:
        print("some other double value that I don't want to print")
    case let someString as String:
        print("a string value of \"\(someString)\"")
    case let (x, y) as (Double, Double):
        print("an (x, y) point at \(x), \(y)")
    case let movie as Movie:
        print("a movie called '\(movie.name)', dir. \(movie.director)")
    case let stringConverter as String -> String:
        print(stringConverter("Michael"))
    default:
        print("something else")
    }
}
 
// zero as an Int
// zero as a Double
// an integer value of 42
// a positive double value of 3.14159
// a string value of "hello"
// an (x, y) point at 3.0, 5.0
// a movie called 'Ghostbusters', dir. Ivan Reitman
// Hello, Michael

一个例子

默认情况下,case后面是不支持Array数组的,如果你使用数组当作case的匹配条件的话,编译就会失败,比如下面这种情况:

let number = 0
let luckyNums = [8, 88, 888]
switch number {
case 0:
    print("= 0.")
case luckyNums: //此处报错
    print("It's lucky number.")
default:
    print("Other.")
}

编译器给你弹了个红红的感叹号,告诉你:Expression pattern of type '[Int]' cannot match values of type 'Int'
意思是,Int值不能与[Int]值进行匹配。

我们都知道计算机是无法对比两个不同类型的值的,很明显,Int是整型,[Int]是整型数组。swift是一门类型安全的语言,即使是UInt16UInt32也不能直接比较,也要转换成UInt16vsUInt16 或者 UInt32vsUInt32才能进行比较,更何况是将值类型和数组类型进行对比。

难道没有办法了吗?

办法是有的!switch-case结构将传入的值与case分支进行比较,编译器会将它们进行模式匹配,也就是~=(不是==)运算符,如果编译器找不到这两种类型的模式匹配规则(方法),那么就会报错,因此我们只需重载~=运算符就可以实现匹配数组了。

添加一个全局的重载方法:

func ~=(lhs: [T], rhs: T) -> Bool {
    for tmp in lhs where rhs == tmp{
        return true
    }
    return false
}

前面的例子中,我们可以看到红色感叹号消失了。number重新赋值:

let number = 8  //or 88, 888

Playground输出:

It's lucky number.

结束

通过重载~=运算符,可以看出swift的代码其实是非常灵活的,工程中可以通过重载运算符、extension、万能的enum等等高级用法来减少代码量,提高代码的可阅读行。

你可能感兴趣的:(Swift重载运算符在switch-case中的模式匹配)