Swift语言指南--可选值

前端之家收集整理的这篇文章主要介绍了Swift语言指南--可选值前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。


在值可能不存在的情况下使用可选值(optional),可选值是:

  ·存在一个值,这个值等于x

  ·不存在任何值

注:

在 C 和 Objective-C 中可选值的概念并不存在。Objective-C 中(与可选值)最相近的(概念)是,一个以对象为返回值的方法,也可以返回 nil,nil表示“不存在有效的对象”。不过,这规则只对对象有效——对于结构、基本的 C 类型或枚举值无效。对于这些类型,Objective-C 语言的方法通常会返回一个特殊值(如NSNotFound@H_502_41@)来表示值不存在。这种策略假定该方法调用方知道要测试返回值是否等于某个特殊值,并且记得要作此检查。Swift 的可选值允许表示任何类型不存在值,无需定义特殊常量。

这里有个例子。Swift 的String@H_502_41@类型有一个名为toInt@H_502_41@方法,可尝试将String@H_502_41@值转为Int@H_502_41@值。然而,不是所有字符串都可以转换为整数。字符串“123”@H_502_41@可以转换为数值123@H_502_41@,而字符串“hello,world”@H_502_41@显然没有对应的数值。

下面的例子会尝试用toInt@H_502_41@方法String@H_502_41@转换为Int@H_502_41@

1 let possibleNumber(可能是数字) = "123"
2 let convertedNumber(转换得到的数字) = possibleNumber.toInt() 
3 //convertedNumber被推断为 "Int?" 类型,或 "可选的 Int"

因为toInt@H_502_41@方法可能会转换失败,因此它返回的是一个可选的Int@H_502_41@型,而不是Int@H_502_41@型。可选的Int@H_502_41@写法为Int?@H_502_41@,而不是Int@H_502_41@。问号表明示该类型包含的值是可选的,即Int?@H_502_41@可能包含某个Int@H_502_41@类型的值,也可能不含任何值。(它不能包含其他类型的值,如Bool@H_502_41@值或String@H_502_41@值,它要么是Int 要么就@H_502_41@不存在。)

if@H_502_41@语句与强制拆包

可使用if@H_502_41@语句测试可选值是否含有值。如果有,则求值结果返回true@H_502_41@,否则返回false@H_502_41@

一旦确认可选值的确含有一个值,就可以通过在可选值变量名的末尾添加感叹号(!@H_502_41@)来访问其内部的值。感叹号明确表达:“我知道这个可选值确实存在值,请使用它(那个值)吧!”这种操作名为对可选值进行强制拆包force-unwrap):

  1. 1 if convertedNumber(转换后得到的数字) {
    2     println(\(possibleNumber) 的整数值为 \(convertedNumber!)")
    3 } else {
    4     println(\(possibleNumber) 不能转换为一个整数5 }
    6 // 输出 "123 的整数值为 123"
  2. @H_860_301@

    关于if@H_502_41@语句的更多信息,请见流程控制

    注:

    尝试用!@H_502_41@访问不存在的可选值时会在运行时报错,在用!@H_502_41@强行拆包之前,务必确保可选值确实包含一个非nil@H_502_41@的值。

    可选值绑定

    可以使用可选值绑定optional binding)测试可选值是否包含一个值,如果有,则将该值以临时常量或变量的形式拆包备用。可选值绑定可以与if@H_502_41@或while@H_502_41@语句结合使用,这样只需要一步就可以检查是否存在值、提取该值、并存放到常量或变量中。关于if@H_502_41@与while@H_502_41@语句的更多信息在流程控制一章中有讲过。

    可选值绑定与 if 混用可以是这样:

    if let constantName = someOptional {
    2     statements
    3 }

    上文中的possibleNumber一例,可以用可选值绑定代替强制拆包:

    if let actualNumber = possibleNumber.toInt() {
    2      println(\(possibleNumber) 的整数值为 \(actualNumber)) 
     {  
    4      println(\(possibleNumber) 无法转换为整数} 
    6   输出 "123 的整数值为 123"

    可以这样理解:

    “如果possibleNumber.toInt()@H_502_41@返回的可选的Int@H_502_41@包含一个值,则新建一个名为actualNumber@H_502_41@的常量,并将常量的值设为可选值中包含的值。”

    如果转换成功,常量actualNumber@H_502_41@将可供if@H_502_41@语句的第一个分支语句使用。该常量已经被可选值包含的值初始化,因此不再需要用后缀!@H_502_41@访问其值。本例中,actualNumber@H_502_41@被直接用来输出转换结果。

    常量与变量均可用于可选值绑定。如果需要在第一个分支中处理actualNumber的值,可以改写为if var actualNumber@H_502_41@,这样可选值的值将作为变量而非常量拆包。

    nil

    要将可选变量设为空值(没有值或值不存在的状态,valueless),可以给它赋特殊值nil@H_502_41@

    var serverResponseCode(服务器状态码): Int? = 404
    服务器状态码包含一个实际存在的 Int 值:404 
    3 serverResponseCode= nil 
    4  服务器状态码 现在不含任何值

    注:

    nil@H_502_41@不能用于非可选值的常量或变量。如果代码中的常量或变量需要适配值不存在的某种特殊情况,务必将它声明为适用的可选值类型

    如果你所定义的可选值未提供默认值,该常量或变量将被自动设为nil@H_502_41@

    var surveyAnswer: String?
     surveyAnswer 被自动设为 nil

    注:

    Swift 的nil@H_502_41@与 Objective-C 的nil@H_502_41@不同。Objective-C 的nil@H_502_41@是指向一个不存在对象的指针,而 Swift 的nil@H_502_41@不是指针——它是一种表示值不存在的特殊类型。任何类型的可选值都能赋值为nil@H_502_41@,不仅限于对象类型。

    可选值的隐式拆包

    如上所述,可选值指允许“值不存在”的常量或变量。可以通过if@H_502_41@语句测试可选值是否存在值,也可以通过可选值绑定按条件拆包,并在该可选值的值存在的情况下才访问它的值。

    有时根据程序结构可以知晓一个可选值在首次赋值后,必然存在值。这时,可以不必每次访问时都检测并提取该可选值的值,因为可以安全地假设它那时一定存在值。

    这些可选值可定义为隐式拆包的可选值(implicitly unwrapped optional)。你可以通过在希望标为可选的类型名称后面,用感叹号 (String!@H_502_41@) 代替问号 (String?@H_502_41@)的方式书写隐式拆包可选值

    隐式拆包的可选值在可选值首次定义后即确认存在值,在此之后任何时刻都能被明确地(肯定有值)使用。Swift 中隐式拆包可选值主要应用于类初始化,详见外部引用与隐式拆包的可选属性(待译)

    隐式拆包的可选值在运行环境里就是普通的可选值,但能够像非可选值那样使用,无需在每次访问时拆包。下例显示可选的 String@H_502_41@隐式拆包的可选 String@H_502_41@之间的行为差异:

    1 let possibleString(可能的字符串): String? = An optional String。(一个可选的String)2 println(possibleString!)  访问其值时需要添加感叹号
     输出 "可选的 String。"
    4 let assumedString(假设的字符串): String! = "An implicitly unwraped optional String。(隐式的拆包的可选Stirng)" 
    5 println(assumedString)  访问其值时无需感叹号 
     输出 "隐式拆包的可选 String。"

    可以认为,隐式拆包的可选值即授予可选值在被使用时自动拆包的权限(即无需再次手动进行拆包)。不必每次使用可选值时都在名称后面添加感叹号,只需在声明时在可选值类型后面加上感叹号即可。

    注:如果在隐式拆包的可选值存在值之前就尝试访问(不存在值时不可进行隐式拆包),运行时会报错。结果与在普通可选值尚未赋值时直接加感叹号就引用相同。

    隐式拆包的可选值也可以当作像普通可选值那样,检查是否存在值:

     assumedString {
        println(assumedString)
     输出 "An implicitly unwraped optional String。(隐式的拆包的可选Stirng)"

    隐式拆包的可选值同样可以使用可选值绑定,单条语句完成检查值并拆包:

    if let definiteString(肯定是字符串) = assumedString(假定是字符串) { 
       println(definiteString)  
     } 
     输出 "隐式拆包的可选 String。"

    注:当变量在后续过程中可能变为nil@H_502_41@时,不应使用隐式拆包的可选值。如果在变量声明周期内都需要检查nil@H_502_41@值,请务必使用普通的可选类型量。



    转自:http://www.cnblogs.com/joejs/p/3777961.html

    原文链接:https://www.f2er.com/swift/324703.html

猜你在找的Swift相关文章