美文网首页
Swift 可选项

Swift 可选项

作者: Aliv丶Zz | 来源:发表于2020-11-01 14:01 被阅读0次
    • 可选项,也叫做可选类型。定义为可选类型后,可以设置为 nil
    • 在类型名后面加个问号?来定义可选类型
    • 可选类型如果不初始化,则默认为nil
    var name : String?  /*等同于*/ var name : String? = nil
    

    1. 强制解包

    • 可选项是对其它类型的一种包装,可以将它理解为一个盒子
    • 如果为 nil,那么它就是一个空盒子
    • 如果不为 nil ,那么盒子里包装的是:被包装类型的数据
    var name : String? = nil
    
    let arr = ["jack","uzi","godV","rookie"]
    func getObj(index:Int) -> String?{
        if index<0 || index >= arr.count {
            return nil
        }else{
            return arr[index]
        }
    }
    
    print(name)
    print(getObj(index: 3))
    /*
    nil
    Optional("rookie")
    */
    
    • 如果要从可选项中取出被包装的数据,则需要使用感叹号 !进行强制解包
    • 如果对值为nil的可选项进行强制解包,将会产生运行时错误
      错误信息:Fatal error: Unexpectedly found nil while unwrapping an Optional value

    2. 可选绑定

    • 可以使用 可选项绑定 来判断可选项是否包含值
    • 如果包含就自动解包,把值赋给一个临时的常量 或者 变量,并返回true,否则返回 false
    let num = Int("123") 
    print(num)//Optional(123)
    
    if let num = Int("123"){
        print("num:",num)//num: 123
    
    }else{
        print("字符串转换失败")
    }
    

    3. if 中的可选绑定

    可选项在进行 与(&&) 运算时。不能直接使用 &&,可以用逗号分隔的方式
    如下:

    if let a = Int("12") {
        if let b = Int("44") {
            if a < b && b < 100 {
                print("\(a) < \(b) < 100")
            }
        }
    }
    
    //等同于
    
    if let a = Int("12"),
       let b = Int("44"),
        a < b && b < 100{
        print("\(a) < \(b) < 100")
    
    }
    

    3. while 中的可选绑定

    //遍历数组,进行累加,如果遇到非数字,停止遍历
    var strs = ["1","2","-3","3","4","5",]
    var index:Int = 0
    var sum:Int = 0
    
    
    while
        index < strs.count,
        let obj = Int(strs[index]){
            sum += obj
            index += 1
    }
    print("sum:",sum)//12
    
    

    4 ?? 空合并运算符

    示例:a ?? b

    a:必须是可选项
    b:可选项 或者 不是可选项
    b跟a的存储类型必须相同

    • 如果 a 不为 nil,则返回 a
    • 如果 a 为 nil, 则返回b
    • 如果b不是可选项,返回 a 时,则a会自动解包
    let a: Int? = 1
    let b: Int? = 2
    let c: Int = 3
    
    let d: Int? = nil
    
    print(a ?? b, a ?? c, d ?? b) //Optional(1) 1 Optional(2)
    
    4.1 ?? 跟if let 配合使用
    • 类似于 if v1 != nil || v2 != nil
    let v1:Int? = nil
    let v2:Int? = 2
    
    if let c = v1 ?? v2{
        print(c)
    }
    //类似于 if v1 != nil || v2 != nil
    
    • 类似于 if v1 != nil && v2 != nil
    let v1:Int? = nil
    let v2:Int? = 2
    if let c = v1,
       let d = v2{
        print("result_c:",c)
        print("result_d:",d)
    
    }
    

    5. guard 语句

    guard 条件 else{
       //退出当前作用域
    } 
    
    • guard 语句的条件为 false 时, 就会执行大括号里的代码
    • guard 语句的条件为true时,就会调过 guard
    • guard 语句特别适合用来 "提前退出"

    注意:当使用guard 语句进行可选绑定时,可选绑定的常量(let)、变量(var)也能在外层作用域中使用

    func login(_ info:[String : String]) -> Bool {
        guard let username = info["username"] else{
            print("用户名不能为空")
    
            return false
        }
        guard let password = info["password"] else{
            print("用户密码不能为空")
            return false
        }
        print("登录中 username:\(username)  password:\(password)")
        return false
    }
    login(["password" : "12345678"])//用户名不能为空
    login(["username" : "Jack"])//用户密码不能为空
    login(["username" : "Jack", "password" : "12345678"])//登录中 username:Jack  password:12345678
    
    

    对比使用 if-else 更加简便

    func login2(_ info:[String : String]) -> Bool {
        let username:String
        
        if let tempUsername = info["username"] {
            username = tempUsername
        }else{
            print("用户名不能为空")
            return false
        }
        
        let password:String
        if let tempPassword = info["password"] {
            password = tempPassword
        }else{
            print("用户密码不能为空")
            return false
        }
        
        print("登录中 username:\(username)  password:\(password)")
    
        return true
    }
    
    

    6. 隐式解包

    • 在某些情况下,可选项一旦诶设定后,就会一直拥有值
    • 这种情况下,可以去掉检查,也不必每次访问的时候都进行解包,因为它能够确定每次访问的时候都有值
    • 可以在类型后面加感叹号!定义一个隐式解包的可选项, 其值不能为 nil
    let num1 :Int! = 1  //虽然是隐式解包,但其仍是可选项
    let num2 :Int = num1 //隐式解包可以直接赋值给Int类型
    
    if let k = num1 {
        print(k)
    }else{
        print("nil")
    }
    
    

    7. 多重可选项

    结构分析
    注意:可以使用lldb指令:frame variable -R或者 fr v -R查看区别

    序号 情况1 情况2
    1 var n1 : Int? = 10 var n1 : Int? = nil
    2 var n2 : Int?? = n1 var n2 : Int?? = n1
    3 var n3 : Int?? = 10 var n3 : Int?? = nil

    对于情况1:

    var n1 : Int?  = 10
    var n2 : Int?? = n1
    var n3 : Int?? = 10
    
    情况1.png 情况1.png

    对于情况2:

    var n1 : Int?  = nil
    var n2 : Int?? = n1
    var n3 : Int?? = nil
    
    情况2.png 情况2.png
    分析:个人觉得😆
    1. 可选类型 some/none {...}中的内容即为盒子里的内容。
    2. none 标识的是空盒子,当为空盒子时。下层{}也就不存在意义
    3. 对于情况2中 n1 n3都为空盒子;n2不是空盒子,盒子里有内容,内容为空

    相关文章

      网友评论

          本文标题:Swift 可选项

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