Swift(optional)
可选类型 Optional
Swift中的Optional作为一种类型,既可以存储一个值,也可以为空(nil),通常在类型后面加一个?表示它是Optional类型的:
var number: Int? = 32
其中?是语法糖,上面写法等价于:
var number: Optional<Int> = 32
打开Optional定义可以看到其枚举定义:
public enum Optional<Wrapped> : ExpressibleByNilLiteral {
case none
case some(Wrapped)
...
}
一个Optional对象只存在两种状态:包含一个值,或者为空,我们都可以通过解包(unwrap)来获取:
var myString: String? = "Hello"
if myString != nil{
//print("\(myString)")
print("\(myString!)")
}
安全使用Optional
我们不能再把Optional当作Boolean值处理:
var myString: String? = "Hello"
if myString {
print(myString)
}
可喜的是编译器会辅助我们修正错误:
if myString != nil{
print("myString contain a string value of \(myString!)")
}
实际上,Swift提供了一种更加方便的形式来完成这一过程:
if let actualString = myString {
print("myString contain a string value of \(actualString )")
} else {
print("myString is nil")
}
注:也可用if var actualString = myString
,此时则actualString为可变量
隐式解包Optional、!
Swift中我们还有一种特殊的Optional,在对它的成员或者方法进行访问时,编译器会自动进行解包,被称为隐式解包:
var possisbleString: String!
在访问时,编译器会自动帮我们完成在变量后插入!的行为
let possibleString: String! = "An implicity unwrapped optional string."
let implicitString: String = possibleString //此处我们不需要!来对possibleString 进行显示解包
使用隐式解包(!)有个风险:尝试访问一个为空的隐式解包Optional, 就会遇到一个runtime error,因此保证隐式解包的类型不为空是必要的。
Optional Chaining
可以通过一个链来安全的访问一个Optional的属性或者方法:
if (leftViewController?.view.superview) != nil){
...
}
当leftViewController为空时,直接返回nil,Optional Chaining帮助我们简化了代码,使我们不必一层层判断非nil
??的使用
var s1: String?
let s2 = s1 ?? "default"
同样语法糖,等价于:
if s1 != nil{
s2=s1
}
else{
s2="default"
}
其它(思考)
let s1: String?
let s2: String?=nil
var s3: String?
var s4: String?=nil
以上4种写法区别?
附上leetCode第二题答案
class Solution {
func addTwoNumbers(_ l1: ListNode?, _ l2: ListNode?) -> ListNode? {
if l1 == nil {
return l2
}
if l2 == nil {
return l1
}
var p1 = l1;
var p2 = l2;
var l3:ListNode?;
var p3:ListNode?;
var flag = 0;
var n1 = 0;
var n2 = 0;
var tmp = 0;
while (p1 != nil || p2 != nil){
n1 = (p1==nil) ?0: p1!.val
n2 = (p2==nil) ?0: p2!.val
tmp = n1+n2+flag
if tmp>=10 {
flag=1
tmp = tmp-10
}
else{
flag=0
}
if p3==nil {
l3 = ListNode(tmp)
p3 = l3
}
else{
p3!.next = ListNode(tmp)
p3 = p3!.next!
}
print(3)
p1 = (p1==nil) ?p1:p1?.next
p2 = (p2==nil) ?p2:p2?.next
}
if flag==1 {
p3!.next = ListNode(1)
}
return l3
}
}
既已览卷至此,何不品评一二: