zoukankan      html  css  js  c++  java
  • swift模式和模式匹配

    模式和模式匹配

    模式:

    代表单个或者复合值得结构,也就是说模式不是一个特定的值,它是一种抽象的结构,【一句话,不是特指,是泛指】。这样就可以用模式来匹配各种各样的值。
    例如:(x,y)可以匹配元祖(1.2),以及任何包含两个元素的元组。
    除了利用模式匹配一个值以外,你可以从复合值中提取出部分或全部值,然后把各个部分的值和一个常量或变量绑定起来。
    swift中的模式分为两类:
    一种能匹配任何类型的值,另一种在运行时匹配某个特定的值,可能会失败。
    第一种模式用于结构简单变量,常量和可选绑定中的值。此类模式包括通配符模式,标识符模式,以及包含前两种模式的值绑定模式和元组模式。你可以为这类模式指定一个类型标注,从而限制它们只能匹配某种特定类型的值。
    第二种模式用于全局模式匹配。这种情况下,你试图匹配的值在运行时可能不存在。此类模式包括枚举用例模式,可选模式,表达式模式和类型转换模式。你在switch语句的case标签中,do语句的catch 子句中,或者再if,while,guard,for-in语句的case条件语句中使用这类模式。

    模式匹配

    通配符模式 ( wildcard pattern)

    通配符模式由一个下划线(_)构成,用于匹配并忽略任何值,当你想忽略被匹配的值时可以使用该模式。

    for _ in 1...3{
        
    }
    

    标识符模式 (identifier pattern)

    标识符模式可以匹配任何值,并将匹配的一个变量或者常量绑定起来

    let someValue = 42
    

    值绑定模式 value-binding pattern

    值绑定模式把匹配到的值绑定给一个变量或者常量,把匹配到的值给常量是,用关键字 let, 绑定给变量时 用关键字 var

    let point = (3, 2)
    switch point {
        //将point中的元素绑定到 x 和 y
    case let (x, y):
        print("point is at x:((x), (y)")
    }
    

    元组模式 (tupel pattern)

    元组模式是由都好分隔的,具有零个或多个模式的列表,并由一对圆括号括起来。元组模式匹配到响应的元组类型值。
    你可以使用类型标注去限制一个元组模式只能匹配那种元组类型。例如, 在常量声明 let(x ,y):(Int, Int) = (1,2)中的元组模式(x,y):(Int,Int)就只能匹配两个元素都是Int类型的元组。

    当元组模式被用于 for-in 语句或者变量和常量声明时,它仅可以包含通配符模式,标识符模式,可选模式或者其他包含这下模式的元组模式。

    let points = [(0, 0), (1, 0), (1, 1), (2, 0), (2, 1)]
    //便利 y==0 x是任意值的元组
    for (x, y) in points where y==0 {
        print("(x) and (y)")
    }
    
    

    枚举用例模式 enumeration case pattern

    枚举用例模式匹配现有的某个枚举类型的某个用例。枚举用例模式出现在switch 语句中的 case 标签中,以及if,while,guard,for-in语句的case条件中。

    可选项模式 optional pattern

    可选项模式匹配 Optional 枚举在some(Wrapped)中包装的值。
    可选项模式为 for-in 语句提供了一种迭代数组的简便方式,只为数组中非 nil 的元素执行循环体

    let someOptional: Int? = 42
    if case .some(let x) = someOptional {
        print(x)//42
    }
    
    if case let x? = someOptional {
        print(x)//42
    }
    
    let arrayOfOptionalInts: [Int?] = [nil, 2, 3, nil, 5]
    for case let number? in arrayOfOptionalInts {
        print("fond a (number)")//2,3,5
    }
    

    类型转换模式 Type-Casting Pattern

    有两种类型转换模式, is模式和as模式, is 模式只出现在switch语句中的case标签中。
    is 模式和 as 模式形式如下:
    is 类型
    模式 as 类型

    *** is 模式仅当一个值的类型在运行时和is模式右边的指定类型一致,或者是其子类的情况下,才会匹配这个值。is模式和is 运算符有相似表现,它们都可进行类型转换,但是is模式没有返回类型 ***
    *** as 模式仅当一个值得类型在运行时和as模式右边指定类型一致或者是其子类的情况下,才会匹配这个值,如果匹配成功,被匹配的值得类型被转换成as模式右边指定的类型 返回***

    protocol Animal {
        var name: String{get}
    }
    
    struct Dog: Animal {
        var name: String {
            return "Dog"
        }
        var runSpeed: Int
    }
    
    
    struct Bird: Animal {
        var name: String {
            return "Bird"
        }
        var flyHeight: Int
    }
    
    struct Fish: Animal {
        var name: String {
            return "fish"
        }
        var depth: Int
    }
    
    let animals: [Any] = [Dog(runSpeed: 10), Bird(flyHeight: 1000), Fish(depth: 300)]
    for animal in animals {
        switch animal {
        case let dog as Dog:
            print("(dog.name) can run (dog.runSpeed)")
        case let fish as Fish:
            print("(fish.name) dive depth (fish.depth)")
        case is Bird:
            print("bird can fly")
        default:
            print("unknown animal")
        }
    }
    
    

    表达式模式 expression pattern

    表达式模式代表表达式模式的值,表达式模式出现在 switch语句的case标签中
    表达式模式代表的表达式会使用Swift 标准库中的 ~= 运算符与输入表达式的值进行比较。如果 ~= 运算符返回true, 则匹配成功。默认情况下, ~= 运算符来比较两个相同类型的值,它也可以将一个整形数组与一个Range实例中的一段整数区间做匹配

    let point = (1,2)
    switch point {
    case (0,0):
        print("(0,0) is at the origin.")
    case (-2...2, -2...2):
        print("((point.0), (point.1)) is near the origin.")
    default:
        print("the point is at ((point.0),(point.1))")
    }
    :(1, 2) is near the origin.
    
    

    自定义类型默认是无法进行表达式模式匹配的,也需要重载 ~= 运算符

    struct Employee {
        var salary: Int
    }
    
    //重载 ~= 才能对自定义的类进行 范围模式匹配
    func ~= (left: ClosedRange<Int>, right: Employee) -> Bool  {
        return left.contains(right.salary)
    }
    
    var e: Employee = Employee(salary: 1000)
    
    switch e {
    case 0...1000:
        print("穷")
    case 1000...5000:
        print("凑合")
    case 5000...1000:
        print("富")
    default:
        print("土豪")
    }
    
  • 相关阅读:
    使用Webuploader大文件分片传输
    php面向对象的封装性
    前端实习经历
    Js_protoType_原型
    SVN客户端与服务器端搭建操作
    安装PL/SQL客户端来访问操作步骤
    安装Oracle数据库操作步骤
    MyEclipse2014安装操作步骤+破解
    模块学习笔记
    json与导入模块目录
  • 原文地址:https://www.cnblogs.com/wjw-blog/p/11674857.html
Copyright © 2011-2022 走看看