Swift学习之七:Optional value(可选值)

当值可能不存在(may be absent)的时候使用Optionals。

optional是说:There is a value, and it equals x.(我个人理解为:存在一个值,这个x就是所得到的值) 

                          或者 There isn't a value at all.(根本不存在值)

NOTE 

在C或者OC中不存在Optionals这个概念。在OC中最最近这个概念意思的是:在函数调用时,返回对象或者返回nil,这个nil意味着

有效对象的absence value.然后,这仅对对象起作用,对结构体、基本C类型或者枚举值类型不起作用,对于这些类型,OC中通过

返回NSNotFound这个特殊的值来表明absence value,通过这个值,函数调用者就可以检测处理。在Swift中,optionals可以是任何

类型,不需要特殊的常量表示。


看下面的例子:

  1. // 这个字符串是完全由数字组成的  
  2. let possibleNumber = "123"  
  3. // 这里调用toInt()方法时,转换可能会失败,所以返回的是Optional类型,也就是Int?类型,  
  4. // 相当于Optional<Int>,返回值是说:要么有整型值,要么根本就没有值  
  5. // 因为这里possibleNumber完全是由数字组成的字符串,所以转换成功,因此得到整型值123  
  6. let convertedNumber = possibleNumber.toInt()  
  7.   
  8. // 这个字符串不是由数字组成的  
  9. let originalString = "hello, world"  
  10. // 这里调用toInt()方法时,转换可能会失败,所以返回的是Optional类型,也就是Int?类型,  
  11. // 因为这里的originalString不是由数字组成的,所以转换失败,返回值就是没有值  
  12. let resultNumber = originalString.toInt()  

If 语句与强制拆包

可以使用if语句来检测optional是否包含值,如果包含值,就表示true,如果根本没有值,就表示false.

当我们确定optional包含值,可以使用!来访问,这个!放在这个optional名字后面。这个!表明:我知道这个

optional一定有值,请使用它。这就是所谓的:可选值的强制拆包(forced upwrapping of the optional's value)

看下面的例子:

  1. // convertedNumber is an optional value  
  2. // 如果convertedNumber存在值,那么表达式就是true  
  3. if convertedNumber {  
  4.   // 如果能够进到这里,表示convertedNumber一定有值,那么我们就可以强制拆包  
  5.   // 强制拆包就是在optional value后面添加一个!,也就是convertedNumber!  
  6.   // 但这也是需要注意的地方,使用强制拆包一定要确保这个可选值有值,否则  
  7.   // 强制拆包会崩溃  
  8.   println("\(possibleNumber) has an integer value of \(convertedNumber!)")  
  9. else {  
  10.   println("\(possibleNumber) could not be converted to an integer")  
  11. }  

NOTE

尝试使用!来访问不存在值的optional value 会触发运行时错误。当我们使用!来强制拆包(force-unwrap)的时候,

一定要确保这个optional value一定包含一个非nil 值。


可选绑定(optional binding)

我们可以使用optional binding来判断这个optional 是否包含一个值,确保值是可用的,并作为临时常量或者变量的值。

Optional binding可以使用if 和 while 语句中,用来检测optional是否包含值,并取出其中的值给常量或者变量。optional 

binding的写法是:

  1. if let constantName = someOptional {  
  2.    statements  
  3. }  


看下面的例子:
  1. let possibleNumber = "123"  
  2. if let actualNumber = possibleNumber.toInt() {  
  3.    println("\(possibleNumber) has an integer value of \(actualNumber)")  
  4. else {  
  5.    println("\(possibleNumber) could cant be converted to an integer")  
  6. }  

上面的例子中,我们只是单纯地打印actualNumber,所以用了let,如果我们需要另外操作,可以用var声明为变量,而不是常量。


可选值变量可以设置为nil,表示没有值

如下:

  1. // 这个optional是Int?类型,初始值为404  
  2. var serverResponseCode: Int? = 404  
  3. // 把serverResponseCode设置为nil后,serverResponseCode现在不再有值,也就是Optional.None  
  4. serverResponseCode = nil  

NOTE

非optional类型常量和变量是不能设置为nil的,这与OC用的nil不同。

如果在代码中不确定这个变量或者常量是否有值,那么就声明为optional。


如果在定义Optional常量或者变量时,没有给定初始值,那么会自动设置为nil,表示Optional.None,即没有值。

如:

  1. // surveyAnswer的值就是nil  
  2. var surveyAnswer: String?   

NOTE

SWIFT中的nil不同与OC中的nil,在OC中,nil表示不存在的对象。在Swit中,nil不是指针,只是表示某种类型的值不存在,

optional可以设置任何类型值为nil,不仅仅是对象类型。


隐式拆包可选值(Implicitly Unwrapped Optionals)

有时候,我们可以确定一旦变量或者常量被创建并初始化后,一直都会有值,那么可以就可以使用隐式拆包方式获取值。

在声明变量时,不是使用?来声明可选值,而是使用!来声明。

如:

  1. let possibleString: String? = "An optional string."  
  2. // 这是强制拆包  
  3. println(possibleString!)  
  4.   
  5. let assumedString: String! = "An implicitly unwrapped optional string."  
  6. // 不需要添加!来拆包  
  7. println(assumedString)  

NOTE

如果尝试访问的隐式拆包可选值不包含值,会触发运行时错误。


我们依然可以你正常的optional一样,使用if或者while 判断隐式拆包可选值是否包含值,如果包含值,会返回true,否则返回false

如:

  1. if assumedString {  
  2.    println(assumedString)  
  3. }  

如果还可以像正常的optional一样使用optional binding来使用隐式拆包可选值。

如:

  1. if let definiteString = assumedString {  
  2.    println(definiteString)  
  3. }  

NOTE

隐式拆包可选值不能出现不包含值的情况,否则会崩溃。所以如果不确定运行时值会不会出现nil,那么使用普通的optional会更好。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值