前提
使用可选项的时候,对应的一般要使用!来强行解包,大多数情况下使用!是有风险的,一不小心就会崩,比如:
func demo(x: Int?, y: Int?){
print(x! + y!)
}
然后调用的时候是这样的demo(x:10,y:100)
,这样一般没有错误的,但是当外面传的参数是nil
的话,那么就会报错,自己可以试试。所以有些人就用if
来解决问题,代码如下:
if x != nil && y != nil {
print(x! + y!)
}else{
print("x或者y为nil")
}
这么写不会出错,但是如果直接使用if
,一不小心会让代码很丑陋。有兴趣的可以去王巍的书中找找看,有用if
的这么判断,你只会觉得很蛋疼。
接着来用第二种方法来做判断:
func demo1(x: Int?, y: Int?) {
/**
??是一个简单的三目
- 如果有值,使用值
- 如果没有值,用??后面的值替代
*/
print((x ?? 0) + (y ?? 0))
let name:String? = nil//= "老王"
print((name ?? "") + "你好")
//'??'操作符号的优先级低,在使用的时候,最好加上()包一下
print(name ?? "" + "你好")//如果上面的string = 老王,那么这儿打印的就是老王,这个是个三目,name为空的话打印`+你好`。
}
这种方法写出来就好看多了,也是很常用的。
然后使用第三种方法:if let / var
func demo2() {
let oName: String? = "老王"
let oAge: Int? = 10
if oName != nil && oAge != nil {
print(oName! + String(oAge!))
}
//if let连用,判断对象的值是否为nil,{}内一定有值,可以直接使用,不需要解包
//if var连用,{}可以对值直接进行修改
if var name = oName, let age = oAge
{
name = "老李"
//进入分支之后,name和age一定有值,不需要解包
//name和age的作用域仅在{}中
print(name + String(age))
}else{
print("name 或 age 为 nil")
}
}
紧接着来使用第四种方法:guard
// guard let 和if刚好相反
func demo3(){
let oName: String? = "老王"
let oAge: Int? = 10
//guard let守护一定有值,如果没有直接返回
guard let name = oName,let age = oAge else {
print("姓名或者年龄为nil")
return
}
//代码行至此,name和age一定有值
//通常哦按段是否有值之后,会做具体的逻辑实现,通常代码多
//如果用if let凭空多了一层分支,guard降低分支层次的办法
//guard是swift2.0推出的
print (name + String(age))
}
最后说说guard let & if let的技巧:
func demo4(name: String?,age:Int?){
//非空的name和age仅在{}内有效
if let name = name,let age = age {
print (name + String(age))
print("--------------")
}
//guard let & if let的技巧
//使用同名的变量接收值,在后续使用的都是非空值,不需要解包
//好处,可以避免起名字的烦恼
guard let name = name, let age = age else {
print("姓名或者年龄为nil")
return
}
print (name + String(age))
// let oName: String? = "老王"
// let oAge: Int? = 10
}
总结
在使用可选项的时候,往往需要解包,和文中举的例子一样,如果你传个nil
的时候就会崩溃,所以需要判断可选项的值,总共介绍了四种方法,推荐使用2,3,4三种方法!