苹果那文档写了一大堆也没有好好的写一下可选值(optional)这个东西。就是在有一个“Optional Chaining”的章节,但是也不是很充分的说明。最后找了半天在“the basics”里墨迹了几句。如果你没找到optional这个东西的话,那你可能也错过了一个很重要的东西,非optional类型的变量,这个变量的值不能是nil。这一点和ObjC以及其他的编程语言如C#、Java什么的差别很大。
1
2
|
var example : String
=
"hello world"
example
=
nil
/
/
ERROR,
Type
'String'
does
not
conform to protocol
'NilLiteralConvertible'
|
Optional的值就是可以为空也可以不为空的。定义的方式是这个样子的:
1
|
var example : String?
=
"hello world"
|
对,就是在类型后面的那个问号。有了这个问号,这个变量就是optional的了。它的值就可以为nil了。但是,你是不能直接访问这个变量。
书接上文,非optional的变量不可以赋值为nil的特点。让编程变的安全。因为,如果不检查是否为空就直接使用的话是编译不过的。如:
1
2
3
|
var example : String?
=
"hello world"
/
/
example
=
nil
var example2 : String
=
example
/
/
ERROR, value of optional
type
'String?'
not
unwrapped
|
错误的提示说的是optional类型的变量没有“拆包”。那么,如何拆包呢。很简单,只要在后面加上一个感叹号就可以了,如:
1
2
3
|
var example : String?
=
"hello world"
/
/
example
=
nil
var example2 : String
=
example!
|
“!”感叹号unwrapp,拆包optional的变量。如果这个变量下有值的话就返回这个值,没有的话就会产生一个运行时的错误。
所以呢,苹果推荐了一种更安全的使用optional类型变量的方法。首先设定一个Employee类。它有一个成员属性为name。
1
2
3
4
5
6
7
|
class
Employee {
var name : String
init(name: String){
self
.name
=
name
}
}
|
然后,初始化一个Employee实例,并设定它是optional的: var e : Employee? = Employee(name:"Tom")。这个时候如果直接访问name属性就会报错,e.name = "Tom Cat" // ERROR。如上所说需要拆包。e!.name = "Tom Cat"。那么安全的方式是什么样呢:
1
2
3
4
5
6
7
8
|
var e : Employee?
=
Employee(
"Tom"
)
if
let en
=
e?.name {
println(
"employee's name is \(en)"
)
}
else
{
println(
"unable to identify the employee"
)
}
|
直接用感叹号的方法访问可能会运行时错误,如:let en = e!.name。
延伸阅读:“?”问号和“!”感叹号。都是Optional<T>的简写。更多请了解swift的泛型和Optional<T>。