Swift 可选类型

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u011374318/article/details/89439438

可选类型

在 Swift 中,可选类型用来处理值可能缺失的情况,表示下面两种情况:

  • 有值,你可以访问该值
  • 没有值

在 Swift 中声明变量时,使用 ?! 来表示声明的变量是可选类型。

let name:String?
var age:Int!

此时,变量 nameage 默认都是 nil,表示空。

?! 的区别在于使用前者声明的变量所包含的值时,需要在变量后添加 ! 符号来解析其所包含的值,而后者是隐式解析,不需要再添加 ! 符号。

如下:

name = "John"
let tmpName:String = name!

age = "18"
let tmp:Int = age

当然,使用隐式解析声明的变量时,即使添加了 ! 符号来强制解析其包含的值也不会报错。但是,需要注意的是,如果可选变量中并不包含值而进行了解析,即便是隐式的,也会报错,因为 nil 不能用于非可选的常量和变量。

除非确定变量赋值后便不可能为 nil ,否则不宜使用 ! 符号声明可选变量。而在使用可选变量时,如果不能确定可选变量中的确包含值,那么不宜使用 ! 符号进行解析。

可选链

在使用可选类型时,如果不确定它是否确实包含值,而又需要访问其可能包含的值的属性、方法或下标时,可以在可选值后添加一个 ? 符号,定义一个可选链。不同于使用 ! 符号进行强制展开,该可选链不会因为无值可展开而发生运行时错误。

并且,可选链调用的返回结果同样是一个可选值,即便真实的属性或方法返回值并非可选类型,因为这些非可选类型会被包装成可选类型,不过对于已经是可选类型的结果并不会再进行包装。

如下面的例子:

class Person: NSObject {
    let name:String
    init(name:String) {
        self.name = name
    }
    
    var apartment:Apartment?
}

class Apartment {
    let unit:String
    var address = ""
    
    init(unit:String) {
        self.unit = unit;
    }
    
    weak var tenant:Person!
    
    func changeAdd(address:String) -> String? {
        self.address = address
        
        return address
    }
}

func test() {
        
	var person = Person.init(name: "John")
	    
	let apart = Apartment.init(unit: "A5")
	    
	person.apartment = apart
	    
	apart.tenant = person

	if let isHas = person.apartment?.tenant?.apartment?.changeAdd(address: "shanghai")?.hasPrefix("shang") {		    
		print(isHas)
	    
	}
}

Apartment 类中,属性 tenant 是隐式可选类型,但在 test 方法中,仍然可以在 tenant 后添加 ? 来构成可选链,当然这里也可以省去 ? ,但是如果同时 tenant 没有值时,程序便会报错。

如下:

func test() {
        
	var person = Person.init(name: "John")
	    
	let apart = Apartment.init(unit: "A5")
	    
	person.apartment = apart
	    
//	apart.tenant = person

	if let isHas = person.apartment?.tenant.apartment?.changeAdd(address: "shanghai")?.hasPrefix("shang") {		    
		print(isHas)
	    
	}
}

而不省略 ? 构成的可选链会检查每一个可选值的取值结果,如果有一个可选值包含的值为 nil ,那么便直接返回 nil

将下面的代码单独成一行,便会发现,isHas 是的结果是 (Bool?)nil ,而从 hasPrefix 方法的定义可知,其返回类型为 Bool ,所以可以得知可选链中的每一个结点的返回结果如果是非可选值,也会被包装为可选值。

let isHas = person.apartment?.tenant.apartment?.changeAdd(address: "shanghai")?.hasPrefix("shang")

参考:
可选类型
可选链
Mr_yinwei

猜你喜欢

转载自blog.csdn.net/u011374318/article/details/89439438
今日推荐