• Swift基础语法 - 可选项


    可选项(Optional)

    • 可选项,一般也叫可选类型,它允许将值设置为 nil
    • 在类型名称后面加个问号 ? 来定义一个可选项
    var name: String? = "CSDN"
    name = nil
    
    var age: Int? //默认就是nil
    age = 30
    age = nil
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    在这里插入图片描述

    var array = [2, 4, 6, 8]
    
    func getNumber(_ index: Int) -> Int? {
        if index < 0 || index >= array.count {
            return nil
        }
        return array[index]
    }
    
    print(getNumber(1)) //Optional(4)
    print(getNumber(-1)) //nil
    print(getNumber(4)) //nil
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    在这里插入图片描述

    强制解包(Forced Unwrapping)

    • 可选项是对其他类型的一层包装,可以将它理解为一个盒子
    • 如果为 nil ,那么它是个空盒子
    • 如果不为 nil ,那么盒子里装的是:被包装类型的数据
    var age: Int? //默认就是nil
    age = 10
    age = nil
    
    • 1
    • 2
    • 3

    在这里插入图片描述

    • 如果要从可选项中取出被包装的数据(将盒子里装的东西取出来),需要使用 感叹号 ! 进行强制解包
    var age: Int? = 20
    
    let ageInt: Int = age!
    
    print(ageInt) //20
    
    • 1
    • 2
    • 3
    • 4
    • 5

    在这里插入图片描述

    • 如果对值为 nil 的可选项(空盒子)进行强制解包,将会产生运行时错误
    var age: Int?
    age!
    
    • 1
    • 2

    在这里插入图片描述

    Fatal error: Unexpectedly found nil while unwrapping an Optional value

    判断可选项是否包含值

    let number = Int("123")
    
    if number != nil {
        print("字符串转成数字成功为:\(number!)")
    }else{
        print("字符串转成数字失败")
    }
    // 字符串转成数字成功为:123
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    可选项绑定(Optional Binding)

    • 可以使用 可选绑定 来判断可选项是否包含值
    • 如果包含就自动解包,把赋值给一个临时的常量( let )或者变量( var ),并返回 true ,否则返回 false
    if let number = Int("123") {
        print("字符串转成数字成功为:\(number)")
        // number 是强制解包之后的Int值
        // number 作用域仅限于这个大括号
    }else{
        print("字符串转成数字失败")
    }
    // 字符串转成数字成功为:123
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    enum Season : Int {
        case spring = 1, summer, autumn, winter
    }
    
    if let season = Season(rawValue: 8){
        switch season {
        case .spring:
            print("the season is spring")
        default:
            print("the season is other")
        }
    } else {
        print("no such season")
    }
    // no such season
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    等价写法

    if let first = Int("5") {
        if let second = Int("45") {
            if first < second && second < 50 {
                print("\(first) < \(second) < 50")
            }
        }
    }
    // 5 < 45 < 50
    
    if let first = Int("5"),
       let second = Int("45"),
       first < second && second < 50 {
        print("\(first) < \(second) < 50")
    }
    // 5 < 45 < 50
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    while 循环中使用可选项绑定

    //遍历数组,将遇到 的正整数都加起来,如果遇到负数或者非数字,则停止遍历
    var array = ["10", "20", "30", "ab", "-20", "40"]
    
    var index = 0
    var sum = 0
    while let num = Int(array[index]), num > 0 {
        sum += num
        index += 1
    }
    print(sum)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    空合并运算符 ?? (Nil - Coalescing Operator)

    public func ?? <T>(optional: T?, defaultValue: @autoclosure () throws -> T?) rethrows -> T?
    
    • 1
    public func ?? <T>(optional: T?, defaultValue: @autoclosure () throws -> T) rethrows -> T
    
    • 1
    • a ?? b
    • a 是可选项
    • b 是可选项 或者 不是可选项
    • ba 的存储类型必须相同
    • 如果 a 不为 nil ,就返回 a
    • 如果 a nil ,就返回 b
    • 如果 b 不是可选项,返回 a 时会自动解包
    let a: Int? = 1
    let b: Int? = 2
    let c = a ?? b // c是Int? , Optional(1)
    
    • 1
    • 2
    • 3
    let a: Int? = nil
    let b: Int? = 2
    let c = a ?? b // c是Int? , Optional(2)
    
    • 1
    • 2
    • 3
    let a: Int? = nil
    let b: Int? = nil
    let c = a ?? b // c是Int? , nil
    
    • 1
    • 2
    • 3
    let a: Int? = 1
    let b: Int = 2
    let c = a ?? b // c是Int , 1
    
    • 1
    • 2
    • 3
    let a: Int? = nil
    let b: Int = 2
    let c = a ?? b // c是Int , 2
    
    • 1
    • 2
    • 3
    let a: Int? = nil
    let b: Int = 2
    //如果不使用 ?? 运算符
    let c: Int
    if let tmp = a {
        c = tmp
    } else {
        c = b
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    多个 ?? 一起使用

    let a: Int? = 1
    let b: Int? = 2
    let c = a ?? b ?? 3 // c是Int , 1
    
    • 1
    • 2
    • 3
    let a: Int? = nil
    let b: Int? = 2
    let c = a ?? b ?? 3 // c是Int , 2
    
    • 1
    • 2
    • 3
    let a: Int? = nil
    let b: Int? = nil
    let c = a ?? b ?? 3 // c是Int , 3
    
    • 1
    • 2
    • 3

    ?? 跟 if let 配合使用

    let a: Int? = nil
    let b: Int? = 2
    if let c = a ?? b {
        print(c)
    }
    //类似于 if a != nil || b != nil
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    let a: Int? = nil
    let b: Int? = 2
    if let c = a , let d = b {
        print(c)
        print(d)
    }
    // 类似于 if a != nil && b != nil
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    if 语句实现登录

    func login(_ info: [String : String]) {
        let username: String
        if let tmp = info["username"] {
            username = tmp
        } else {
            print("请输入用户名")
            return
        }
        let password: String
        if let tmp = info["password"] {
            password = tmp
        } else {
            print("请输入密码")
            return
        }
        // if username ....
        // if password ....
        print("用户名:\(username)", "密码:\(password)", "登陆ing")
    }
    login(["username" : "jack", "password" : "123456"]) // 用户名:jack 密码:123456 登陆ing
    login(["password" : "123456"]) // 请输入密码
    login(["username" : "jack"]) // 请输入用户名
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    guard 语句

    guard 条件 else {
        // do something....
        退出当前作用域
        //return、break、continue、throw error
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • guard 语句的条件为 false 时,就会执行大括号里面的代码
    • guard 语句的条件为true时,就会跳过 guard 语句
    • guard 语句特别适合用来“提前退出”
    • 当使用 guard 语句进行可选项绑定时,绑定的常量( let )、变量( var )也能在外层作用域中使用
    func login(_ info: [String : String]){
        guard let username = info["username"] else {
            print("请输入用户名")
            return
        }
        guard let password = info["password"] else {
            print("请输入密码")
            return
        }
        // if username ...
        // if password ...
        print("用户名:\(username)","密码:\(password)","登录ing")
    }
    login(["username" : "jack", "password" : "123456"]) // 用户名:jack 密码:123456 登陆ing
    login(["password" : "123456"]) // 请输入密码
    login(["username" : "jack"]) // 请输入用户名
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    隐式解包(Implicitly Unwrapped Optional)

    • 在某些情况下,可选项一旦被设定值之后,就会一直拥有值
    • 在这种情况下,可以去掉检查,也不必每次访问的时候都进行解包,因为它能确定每次访问的时候都有值
    • 可以在类型后面加个感叹号 !定义一个隐式解包的可选项
    let num1: Int! = 10
    let num2: Int = num1
    if num1 != nil {
        print(num1 + 6) // 16
    }
    if let num3 = num1 {
        print(num3) // 10
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    let num1: Int! = nil
    //Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value
    let num2: Int = num1
    
    • 1
    • 2
    • 3

    在这里插入图片描述

    字符串插值

    • 可选项在字符串插值或直接打印时,编译器会发出警告
    var age: Int? = 10
    print("My age is \(age)")
    
    • 1
    • 2

    在这里插入图片描述

    • 至少有3种方法消除警告
    print("My age is \(age!)")
    //My age is 10
    
    print("My age is \(String(describing: age))")
    //My age is Optional(10)
    
    print("My age is \(age ?? 0)")
    //My age is 10
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    多重可选项

    var num1: Int? = 10
    var num2: Int?? = num1
    var num3: Int?? = 10
    
    print(num2 == num3) // true
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 可以使用lldb指令 frame variable –R 或者 fr v –R 查看区别
    var num1: Int? = nil
    var num2: Int?? = num1
    var num3: Int?? = nil
    
    print(num2 == num3) // false
    
    (num2 ?? 1) ?? 2 // 2
    (num3 ?? 1) ?? 2 // 1
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
  • 相关阅读:
    Java网络编程
    如何在电脑和 SD 卡上恢复已删除 MOV等视频文件
    教程图文详解 - 网络互联与互联网(第六章)
    [spring] spring boot 简述,devtool 配置,actuator 简述,即 properties 配置
    Binary Number Encoding and Arithmetic
    编译器优化丨Cache优化
    C#停车场管理系统
    面试题:SpringBoot 自动装配原理
    解决 vscode使用Prettier格式化js文件报错:Cannot find module ‘./parser-babylon‘
    头歌python二手房数据统计
  • 原文地址:https://blog.csdn.net/weixin_36162680/article/details/128718050