Swif学习之可选类型(optional)详解

版权声明:不积跬步无以至千里,不积小流无以成江海! https://blog.csdn.net/Bolted_snail/article/details/86645576

可选类型

  • Swift中所有数据类型声明的变量或常量都不能为空值(nil)。
var a3: Int = 10
a3 = nil
let str3: String = nil
  • 上面直接给变量或常量赋值为nil会报错的,因为IntString类型不能接受nil。因此Swift为每一种数据类型提供一种可选类型,即每个数据类型后面加上问好(❓)或者叹号(!)。上面变量声明为可选类型正确写法如下:
var a3: Int! = 10
a3 = nil
let str3: String? = nil
  • Int!String?都是IntString的可选类型,它们可以接受nil。

可选类型值拆包

  • 拆包是将可选类型变成普通类型。
let str3: String? = "str"
print(str3)
  • 上面可选类型打印结果为Optional("str"),并不是String类型,所以不能对其进行一些字符串的操作,也不能拼接给其他字符串。
  • 因此对可选类型进行拆包是必要的,拆包分为显示拆包隐式拆包
  • 显示拆包:使用问号(❓)声明的可选类型在拆包时需要使用叹号(!),这种拆包方式称为显示拆包
  • 隐式拆包:使用叹号(!)声明的可选类型在拆包时可以不使用叹号(!),这种拆包方式称为隐式拆包。当然也可以使用叹号(!)进行拆包。
var n1:Int? = 10
//显示拆包
print(n1! + 100)

var n2:Int! = 10
//隐式拆包
print(n2 + 100)
//隐式拆包也可以使用叹号!
print(n2! + 100)
  • 隐式拆包的声明方式通常用于可选类型的值可以确定为非空的情况。

可选绑定

  • 在不能保证可选类型值是否为非空之前最好不要拆包,否可能出现运行时错误。
func divide(n1:Int,n2:Int) -> Double? {
    if n2 == 0{
        return nil
    }else{
        return Double(n1)/Double(2)
    }
}
let result = divide(n1: 1000, n2: 0)
print(result!) //报错

上面result是值为空(nil)的可选类型,如果没有判断就拆包运行时是会报错的,报错如下:nil解包报错
报错原因还是因为拆包后的普通类型是不能接受nil。

  • 我们可以判断可选类型值是否为nil来决定是否拆包:
    方式1:
if result != nil {
    print(result!)
}

方式2:

if let result2 = divide(n1: 1000, n2: 0){
    print(result2)
}else{
    print("failure")
}
  • 其中方式2就是可选绑定。
  • 可选绑定:可选类型在if或while语句中赋值并进行判定的写法称为可选绑定。可选绑定做了两件事情:首先判断表达式值是否为空(nil),如果为非空就将可选类型值拆包并赋值给一个常量;常量的作用域是if或while语句为true的分支。(所以方式2中result2在else之前有效,之后则无效)。

可选链

class Employee{
    var name = ""
    var no = 0
    var job = ""
    var dept: Department?
}
class Department{
    var no = 10
    var name = "Sales"
    var comp: Company?
    
}
class Company {
    var no = 888666
    var name = "阿里巴巴"
}


let emp = Employee()
//print(emp.dept!.comp!.name) //直接报错
print(emp.dept?.comp?.name as Any)
emp.dept = Department()
emp.dept?.comp = Company()
print(emp.dept!.comp!.name)
print(emp.dept?.comp?.name as Any)

可选链
可见直接显示拆包如果可选链中摸个值为nil,会导致代码运行时错误。使用?代替!的位置,如果某个环节为nil,不会报错,而是会吧nil给引用者,如果有值就是一个可选值,我们可以根据可选绑定再做进一步的判断处理。这种由问好(?)引用可选类型的方式就是可选链

  • 可选链是一种温柔的引用方式,它引用的目标不仅仅是属性,还可以是方法、下表、嵌套类型等。

使用?和!的含义

  • 可选类型中的?:声明这个类型是可选类型,访问这种类型的变量或常量需要用!解包。(显示声明可选类型)
  • 可选类型中的!:声明这个类型是也是可选类型,访问这种了星星的变量或常量可以不需要用!解包。(显示声明可选类型)(隐示声明可选类型)
  • 可选链中的!:温柔的访问引用可选类型,避免可选链中因为出现nil而导致运行时错误。

猜你喜欢

转载自blog.csdn.net/Bolted_snail/article/details/86645576