美文网首页
22-模式匹配

22-模式匹配

作者: bytebytebyte | 来源:发表于2020-10-30 12:57 被阅读0次
    //模式匹配
    /*
     1.模式
     什么是模式?模式是用于匹配的规则,比如switch的case、捕捉错误的catch、if/guard/while/for语句的条件等
     swift中金的模式有8个:
     通配符模式、标识符模式、值绑定模式、元组模式、
     枚举case模式、可选模式、类型转换模式、表达式模式
     2.通配符模式
     _ 匹配任何值 _?匹配非nil值
     */
    enum Life {
        case human(name: String, age: Int?)
        case animal(name: String, age: Int?)
    }
    func check(_ life: Life) {
        switch life {
        case .human(let name, _):
            print("human", name)
        case .animal(let name, _?):
            print("animal", name)
        default:
            print("other") //animal age=nil空的情况
        }
    }
    check(.human(name: "Rose", age: 20)) //human Rose
    check(.human(name: "Jack", age: nil)) //human Jack
    check(.human(name: "Dog", age: 5)) //human Dog
    check(.human(name: "Cat", age: nil)) //human Cat
    
    //3.标识符模式:给对应的变量、常量名赋值
    var age = 10
    var name = "Jack"
    
    //4.值绑定模式
    let point = (3, 2)
    switch point {
    case let (x, y):
        print("The point is at (\(x), \(y)).") //The point is at (3, 2).
    }
    
    //5.元组模式
    let points = [(0, 0), (1, 0), (2, 0)]
    for (x, _) in points {
        print(x)
    }
    let names: String? = "Jack"
    let ages = 18
    let infos: Any = [1, 2]
    
    switch (names, ages, infos) {
    case (_?, _, _ as String):
        print("case")
    default:
        print("default") //default
    }
    
    var scores = ["Jack" : 98, "Rose" : 100, "Kate" : 86]
    for (name, score) in scores {
        print(name, score)
    }
    
    //6.枚举case模式
    //if case 语句等价于只有1个case的switch语句
    let num = 2
    //原来写法
    if num >= 0 && num <= 9 {
        print("[0, 9]") //[0, 9]
    }
    //枚举case模式
    if case 0...9 = num{
        print("[0, 9]") //[0, 9]
    }
    //1个case的switch语句
    switch num {
    case 0...9:
        print("[0, 9]") //[0, 9]
    default:
        break
    }
    
    let nums: [Int?] = [2, 3, nil, 5]
    for case nil in nums {
        print("有nil值") //有nil值
        break
    }
    
    let pointss = [(1, 0), (2, 1), (3, 0)]
    for case let (x, 0) in pointss {
        print(x) //1 //3
    }
    
    //7.可选模式
    let height: Int? = 42
    if case .some(let x) = height { print(x) } //等价下一句 //42
    if case let x? = height { print(x) } //42
    
    let heights: [Int?] = [nil, 2, 3, nil, 5]
    for case let height? in heights {
        print(height) //2 //3 //5
    }
    //等价下边for
    for item in heights {
        if let height = item {
            print(height)
        }
    }
    
    func checks(_ num: Int?) {
        switch num {
        case 2?: //非空里边包装是2
            print("2")
        case 4?:
            print("4")
        case 6?:
            print("6")
        case _?:
            print("other")
        case _:
            print("nil")
        }
    }
    checks(4) //4
    checks(8) //other
    checks(nil) //nil
    
    //8.类型转换模式
    let number: Any = 6
    switch number {
    //case is Int:  //编译器依然认为number 是Any类型
    //    print("is Int", number)
    case let n as Int:
        print("is Int", n + 1) //is Int 7
    default:
        break
    }
    
    class Animal {
        func eat(){
            print(type(of: self), "eat")
        }
    }
    class Dog: Animal {
        func run() {
            print((type(of: self), "run"))
        }
    }
    class Cat: Animal {
        func jump() {
            print(type(of: self), "jump")
        }
    }
    func check(_ animal: Animal) {
        switch animal {
        case let dog as Dog:
            dog.eat()
            dog.run()
        case is Cat:
            animal.eat() //run jump
            (animal as? Cat)?.jump() //Cat jump //不能直接调得转
        default:
            break
        }
    }
    check(Dog()) //Dog eat //(__lldb_expr_41.Dog, "run")
    check(Cat()) //Cat eat
    
    //9.表达式模式:用在case中
    let dot = (1, 2)
    switch dot {
    case (0, 0):
        print("(0, 0) is at origin.")
    case (-2...2, -2...2):
        print("(\(dot.0),\(dot.1)) is near the origin.") //(1,2) is near the origin.
    default:
        print("The dot is at (\(dot.0),\(dot.1)).")
    }
    
    //10.自定义表达式模式
    struct Student {
        var score = 0, name = ""
        //pattern:case后面的内容
        //value:switch后面的内容
        static func ~= (pattern: Int, value: Student) -> Bool {
            value.score >= pattern
        }
        static func ~= (pattern: ClosedRange<Int>, value: Student) -> Bool{
            pattern.contains(value.score)
        }
        static func ~= (pattern: Range<Int>, value: Student) -> Bool {
            pattern.contains(value.score)
        }
    }
    var stu = Student(score: 75, name: "Jack")
    switch stu {
    case 100: print(">=100")
    case 90: print(">=90")
    case 80..<90: print("[80, 90)")
    case 60..<79: print("[60, 79)")
    case 0: print(">=0")
    default: break
    } //[60, 79)
    
    if case 60 = stu {
        print(">=60") //>=60
    }
    var info = (Student(score: 70, name: "Jack"), "及格")
    switch info {
    case let (60, text):
        print(text)
    default:
        break
    } //及格
    
    //11.自定义表达式模式
    extension String {
        static func ~= (pattern: (String) -> Bool, value: String) -> Bool {
            pattern(value)
        }
    }
    //prefix == "21"
    //str == "123455"
    func hasPrefix(_ prefix: String) -> ((String) -> Bool) {
        return {
            (str: String) -> Bool in
            str.hasPrefix(prefix)
        }
    }
    //省略后是 结合省略前去理解下面
    //func hasPrefix(_ prefix: String) -> ((String) -> Bool) {
    //    {
    //        $0.hasPrefix(prefix)
    //    }
    //}
    func hasSuffix(_ suffix: String) -> ((String) -> Bool) {
        {
            $0.hasSuffix(suffix)
        }
    }
    var str = "jack"
    switch str {
    case hasPrefix("j"), hasSuffix("k"):
        print("以j开头,以k结尾") //以j开头,以k结尾
    default:
        break
    }
    //不自定义表达式匹配的话等价如下
    //if str.hasPrefix("123") || str.hasSuffix("456") {
    //
    //}
    
    //12.自定义表达式模式
    func isEven(_ i: Int) -> Bool {
        i % 2 == 0
    }
    func isOdd(_ i: Int) -> Bool {
        i % 2 != 0
    }
    extension Int {
        static func ~= (pattern: (Int) -> Bool, value: Int) -> Bool {
            pattern(value)
        }
    }
    var numb = 9
    switch numb {
    case isEven:
        print("偶数")
    case isOdd:
        print("奇数") //奇数
    default:
        print("其他")
    }
    
    prefix operator ~>
    prefix operator ~>=
    prefix operator ~<
    prefix operator ~<=
    prefix func ~> (_ i: Int) -> ((Int) -> Bool) {
        {
            $0 > i
        }
    }
    prefix func ~>= (_ i: Int) -> ((Int) -> Bool) {
        {
            $0 >= i
        }
    }
    prefix func ~< (_ i: Int) -> ((Int) -> Bool) {
        {
            $0 < i
        }
    }
    prefix func ~<= (_ i: Int) -> ((Int) -> Bool) {
        {
            $0 <= i
        }
    }
    var n = 9
    switch n {
    case ~>=0:
        print("1") //1
    case ~>=10:
        print("2")
    default:
        break
    }
    
    //13.where 在5种情况下的使用
    var data = (10, "Jack")
    switch data {
    case let (age, _) where age > 10:
        print(data.1, "age > 10")
    case let (age, _) where age > 0:
        print(data.1, "age > 0") //Jack age > 0
    default:
        break
    }
    
    var agess = [10, 20, 44, 23, 55]
    for age in agess where age > 30 {
        print(age) //44 //55
    }
    
    protocol Stackable {
        associatedtype Element
    }
    protocol Container {
        associatedtype Stack : Stackable where Stack.Element : Equatable
    }
    
    func equal<S1: Stackable, S2: Stackable>(_ s1: S1, _s2: S2) -> Bool where S1.Element == S2.Element, S1.Element : Hashable {
        return false
    }
    
    extension Container where Self.Stack.Element : Hashable {}
    

    相关文章

      网友评论

          本文标题:22-模式匹配

          本文链接:https://www.haomeiwen.com/subject/utwfmktx.html