閱讀879 返回首頁    go 阿裏雲 go 技術社區[雲棲]


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

  上一篇:go linux下at&amp;t匯編下的編程編譯體會
  下一篇:go cmp指令at&amp;t匯編簡單例子注解