理解Swift中Optional类型-有和无的哲学
原文连接:http://blog.barat.cc/ios/understanding-swift-optional/ ###nil的遗憾 当某个变量或表达式没有任何内容时,在Objective-C中可以使用 int i = (int)(nil)+20; //可以这样吗?
因为 ###Optional基础概念 或许是因为上述例子中提到的问题,在某些特定的场景下的确需要表示「无」的存在,因此Swift中引入了Optional类型。 在深入讨论之前,先看看Optional是什么吧! public enum Optional<Wrapped> : _Reflectable,NilLiteralConvertible { case None case Some(Wrapped) public init() public init(_ some: Wrapped) @warn_unused_result public func map<U>(@noescape f: (Wrapped) throws -> U) rethrows -> U? @warn_unused_result public func flatMap<U>(@noescape f: (Wrapped) throws -> U?) rethrows -> U? public init(nilLiteral: ()) } 可以看到Swift中Optional其实是一个枚举类型,其中包含了 var someNumber: Int? var anotherNumber: Int = 100 var someStr: String? var anotherStr: String = "Hello World" 使用问号 变量存在的意义在于:可以参与运算并完成一定的业务要求。接下来我们对上述示例代码中的变量进行一定的运算,再观察结果分析。假设,给 var someNumber: Int? //值为nil var anotherNumber: Int = 100 //值为100 someNumber = someNumber + 100 //编译错误,不能对nil进行操作 anotherNumber = anotherNumber + 100 //正常 为什么会这样呢?按照在Objective-C中的理解看来:一个变量的值是nil,则指向数字0,是可以进行运算的「一开始的示例中我们正是这么做的」。显然, 变量 var someNumber: Int? someNumber = 100 //赋值 someNumber = someNumber + 100 //还是无法通过编译,不能对Optional直接操作 在Swift中对一个Optional类型的变量直接进行操作,是不允许的。这又是为什么呢?大家还记得吗?Optional是枚举类型,不经过任何转换直接和 ###Optional类型转换 在对一个Optional类型的变量进行操作之前,需要先将其转换成可操作的具体类型。你可以把它理解成:在吃掉盒子里面存放的苹果之前,需要先将苹果从盒子中取出来。这个过程可以使用符号 var someNumber: Int? someNumber = 100 //赋值 someNumber = someNumber! + 100 //将苹果从盒子中取出来,再加上100 但是在将苹果从盒子中取出来的时候,你却需要面对一个严肃的哲学问题:**盒子中确实有苹果吗?**如果上述代码中缺少赋值表达式 var someNumber: Int? // someNumber = 100 if(someNumber != nil) { someNumber = someNumber! + 100 } else { print("盒子中根本木有苹果") } 上述代码安全了,可是每个Optional类型的变量在使用之前,都需要对其进行 其中第一个办法,称之为 let authorName: String? = "Barat Semet" let authorAge: Int? = 30 if let name: String = authorName,age: Int = authorAge { print("本文作者 (name) 今年 (age) 岁了") } else { print("作者名称or年龄未指定") } 另外一种方法称之为 var someNumber: Int? var number: Int = someNumber ?? 0 //若someNumber不为nil则获取其值,若为nil则获取0 上述打代码大致等价于: var someNumber: Int? var number: Int if let unwrapped:Int = someNumber { number = unwrapped } else { number = 0 } ###swift-case和guard 我们已经看到了在处理Optional时如何使用 使用 var changshaProgrammer: Double? = 10000000 //长沙市序猿总数 switch changshaProgrammer { case 0?: print("长沙市木有程序猿类") case (1..<1000)?: print("长沙市程序猿类竟然不到1000人") case .Some(let x): print("长沙市有 (x)程序猿类") case .None: print("我们不知道长沙市有多少程序猿类") } 除了上述这种方式之外,我们也可以使用 func sayProgrammerCount(count: Double) -> String { guard let pop: Double = count else { return "我们不知道长沙有多少程序猿类" } return "长沙有程序猿类 (pop) 人" } print(sayProgrammerCount(1000000)) ###最后的总结 和Objective-C不同,在Swift代码中我们拿到某个表达式返回的Optional值时,如果非常确定该表达式的结果不会是 ###参考
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |