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可以是任何
類型,不需要特殊的常量表示。
看下麵的例子:
// 這個字符串是完全由數字組成的 let possibleNumber = "123" // 這裏調用toInt()方法時,轉換可能會失敗,所以返回的是Optional類型,也就是Int?類型, // 相當於Optional<Int>,返回值是說:要麼有整型值,要麼根本就沒有值 // 因為這裏possibleNumber完全是由數字組成的字符串,所以轉換成功,因此得到整型值123 let convertedNumber = possibleNumber.toInt() // 這個字符串不是由數字組成的 let originalString = "hello, world" // 這裏調用toInt()方法時,轉換可能會失敗,所以返回的是Optional類型,也就是Int?類型, // 因為這裏的originalString不是由數字組成的,所以轉換失敗,返回值就是沒有值 let resultNumber = originalString.toInt()
If 語句與強製拆包
可以使用if語句來檢測optional是否包含值,如果包含值,就表示true,如果根本沒有值,就表示false.
當我們確定optional包含值,可以使用!來訪問,這個!放在這個optional名字後麵。這個!表明:我知道這個
optional一定有值,請使用它。這就是所謂的:可選值的強製拆包(forced upwrapping of the optional's value)
看下麵的例子:
// convertedNumber is an optional value // 如果convertedNumber存在值,那麼表達式就是true if convertedNumber { // 如果能夠進到這裏,表示convertedNumber一定有值,那麼我們就可以強製拆包 // 強製拆包就是在optional value後麵添加一個!,也就是convertedNumber! // 但這也是需要注意的地方,使用強製拆包一定要確保這個可選值有值,否則 // 強製拆包會崩潰 println("\(possibleNumber) has an integer value of \(convertedNumber!)") } else { println("\(possibleNumber) could not be converted to an integer") }
NOTE
嚐試使用!來訪問不存在值的optional value 會觸發運行時錯誤。當我們使用!來強製拆包(force-unwrap)的時候,
一定要確保這個optional value一定包含一個非nil 值。
可選綁定(optional binding)
我們可以使用optional binding來判斷這個optional 是否包含一個值,確保值是可用的,並作為臨時常量或者變量的值。
Optional binding可以使用if 和 while 語句中,用來檢測optional是否包含值,並取出其中的值給常量或者變量。optional
binding的寫法是:
if let constantName = someOptional { statements }
let possibleNumber = "123" if let actualNumber = possibleNumber.toInt() { println("\(possibleNumber) has an integer value of \(actualNumber)") } else { println("\(possibleNumber) could cant be converted to an integer") }
上麵的例子中,我們隻是單純地打印actualNumber,所以用了let,如果我們需要另外操作,可以用var聲明為變量,而不是常量。
可選值變量可以設置為nil,表示沒有值
如下:
// 這個optional是Int?類型,初始值為404 var serverResponseCode: Int? = 404 // 把serverResponseCode設置為nil後,serverResponseCode現在不再有值,也就是Optional.None serverResponseCode = nil
NOTE
非optional類型常量和變量是不能設置為nil的,這與OC用的nil不同。
如果在代碼中不確定這個變量或者常量是否有值,那麼就聲明為optional。
如果在定義Optional常量或者變量時,沒有給定初始值,那麼會自動設置為nil,表示Optional.None,即沒有值。
如:
// surveyAnswer的值就是nil var surveyAnswer: String?
NOTE
SWIFT中的nil不同與OC中的nil,在OC中,nil表示不存在的對象。在Swit中,nil不是指針,隻是表示某種類型的值不存在,
optional可以設置任何類型值為nil,不僅僅是對象類型。
隱式拆包可選值(Implicitly Unwrapped Optionals)
有時候,我們可以確定一旦變量或者常量被創建並初始化後,一直都會有值,那麼可以就可以使用隱式拆包方式獲取值。
在聲明變量時,不是使用?來聲明可選值,而是使用!來聲明。
如:
let possibleString: String? = "An optional string." // 這是強製拆包 println(possibleString!) let assumedString: String! = "An implicitly unwrapped optional string." // 不需要添加!來拆包 println(assumedString)
NOTE
如果嚐試訪問的隱式拆包可選值不包含值,會觸發運行時錯誤。
我們依然可以你正常的optional一樣,使用if或者while 判斷隱式拆包可選值是否包含值,如果包含值,會返回true,否則返回false
如:
if assumedString { println(assumedString) }
如果還可以像正常的optional一樣使用optional binding來使用隱式拆包可選值。
如:
if let definiteString = assumedString { println(definiteString) }
NOTE
隱式拆包可選值不能出現不包含值的情況,否則會崩潰。所以如果不確定運行時值會不會出現nil,那麼使用普通的optional會更好。
最後更新:2017-04-03 07:56:55