Swift5.x入门18--字面量,模式匹配,条件编译

字面量

var age = 10
var isRed = false
var name = "liyanyan"
  • 其中10falseliyanyan是字面量;

常见的字面量类型

  • public typealias Float32 = Float
  • public typealias Float64 = Double
  • public typealias IntegerLiteralType = Int
  • public typealias FloatLiteralType = Double
  • public typealias BooleanLiteralType = Bool
  • public typealias StringLiteralType = String
  • 在Swift中绝大部分自带的类型,都支持直接通过字面量进行初始化,Bool,Int,String,Double,Array,Dictionary,Set,Optional,Float等

字面量协议

  • Swift中绝大部分自带的类型,都支持直接通过字面量进行初始化,原因在于它们遵守了字面量协议;
  • Bool:ExpressibleByBooleanLiteral
  • Int:ExpressibleByIntergerLiteral
  • Float,Double:ExpressibleByFloatLiteral
  • Dictionary:ExpressibleByDictionaryLiteral
  • String:ExpressibleByStringLiteral
  • Array,Set:ExpressibleBySetLiteral
  • Optional:ExpressibleByNilLiteral

字面量协议的应用

模式匹配

  • 模式:用于匹配的规则,比如switch的case,捕捉错误的catch等;
通配符模式
  • _ 匹配任何值;
  • _? 匹配非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")
    }
}
  • case .human(let name, _):表示life是human类型且name有值,age可以为任何值;
  • case .animal(let name, _?):表示life是animal类型且name有值,age不能为空;

标识符模式

  • 给对应的变量,常量名赋值;
var age = 10
var isRed = false
var name = "liyanyan"

值绑定模式

let point = (3,2)
switch point {
case let (x,y):
    print("point",x,y)
}
  • 将3和2分别绑定到x,y;

元组模式

let points = [(0,0),(1,0),(2,0)]

for (x,_) in points {
    print(x)
}
let name: String? = "Li"
let age = 18
let info: Any = [1,2]

switch (name,age,info){
case (_?, _, _ as String):
    print("case")
default:
    print("default")
}

枚举case模式

let age = 2

func test() {
    if age >= 0 && age <= 9 {
        print("[0,9]")
    }

    if case 0...9 = age {
        print("[0,9]")
    }
     
    guard case 0...9 = age else {
        return
    }
    print("[0,9]")
}
let ages: [Int?] = [2,3,nil,5]
for case nil in ages {
    print("有nil值")
    break
}
let points = [(1,0),(2,1),(3,0)]

for case let (x,0) in points {
    print(x)
}
可选模式
let age: Int? = 33

if case let x? = age{
    print(x)
}

if case .some(let x) = age {
    print(x)
}

let ages: [Int?] = [nil,2,3,4,nil]

for case let age? in ages {
    print(age)
}

for item in ages {
    if let age = item {
        print(age)
    }
}
 
func check(_ num: Int?) {
    switch num {
    case 2?: //首先不为空,且数据为2
        print("2")
    case 4?:
        print("2")
    case _?:
        print("other")
    case _:
        print("nil")
    }
}
类型转换模式
let num: Any = 6

func test() {
    switch num {
    case is Int:
        //num 依然是Any类型
        print("is Int",num)
    default:
        break
    }
}


func test1() {
    switch num {
    case let n as Int:
        //num 依然是Any类型
        //n 是Int
        print("as Int",n + 1)
    default:
        break
    }
}
表达式模式
let point = (1,2)

func test() {
    switch point {
    case (0,0):
        print("(0,0)")
    case (-2...2,-2...2):
        print("-2,-2")
    default:
        print("the point is x,y")
    }
}
自定义表达式模式
  • 可以通过重载运算符,自定义表达式模式的匹配规则;
  • case底层调用的是~=运算符,那么我们通过重载~=运算符,实现自定义表达式模式的匹配规则;
struct Student {
    var score = 0
    var 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)
    }
}

func test() {
    var s = Student(score: 55, name: "Jack")

    switch s {
    case 100:
        print(">=100")
    case 90:
        print(">=90")
    case 80...89:
        print("[89]")
    case 60...79:
        print("[60,79]")
    default:
        print(">=0")
    }
}
  • 实现字符串匹配;
extension String {
    static func ~=(pattern: (String) -> Bool,value: String) -> Bool {
        pattern(value)
    }
}

func hasPrefix(_ prefix: String) -> ((String) -> Bool) {
    {
        (str: String) -> Bool in
        return str.hasPrefix(prefix)
    }
}

func hasSuffix(_ suffix: String) -> ((String) -> Bool) {
    {
        (str: String) -> Bool in
        return str.hasSuffix(suffix)
    }
}

var str: String = "123456"
switch str {
case hasPrefix("123"):
    print("以123开头")
case hasSuffix("456"):
    print("以456结尾")
default:
    break
}

where

  • 可以使用where为模式匹配增加匹配条件;

条件编译

//操作系统
#if os(macOS) || os(iOS)

//CPU架构
#elseif arch(x86_64) || arch(arm64)

//swift版本
#elseif swift(<5) && swift(>=3)

//模拟器
#elseif targetEnvironment(simulator)

//可倒入某模块
#elseif canImport(Foundation)

#else

#endif

日志打印

  • 实现在Debug模式在打印日志,在Release模式下不打印日志;
  • 新建log.swift文件,实现自定义log方法,如下:
import Foundation

func log<T>(_ msg: T,file: NSString = #file,line: Int = #line,fn: String = #function) {
    #if DEBUG
    let prefix = "\(file.lastPathComponent)_\(line)_\(fn):"
    print(prefix,msg)
    #endif
}

系统版本检测

if #available(iOS 10, macOS 10.12, *){
    //对于iOS平台 只在iOS 10及以上版本执行
    //对于macOS平台 只在macOS 10.12及以上版本执行
    //* 表示在其他所有平台都执行
    
}

API的可用性

//Person的使用条件
@available(iOS 12,macOS 10.15, *)
class Person {}

struct Student {
    //方法study_已经改名为study
    @available(*,unavailable,renamed: "study")
    func study_() {}
    func study() {}
    
    //run方法在iOS11 macOS10.12版本已经废弃
    @available(iOS,deprecated: 11)
    @available(macOS,deprecated: 10.12)
    func run() {}
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容