Swift Optional

322 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第30天,点击查看活动详情


  1. Swift Optional
  2. Swift Enum
  3. iOS开发 做一个三角形
  4. Swfit 指针类型
  5. Swift 属性(下)
  6. Swift 属性
  7. Swift 小结
  8. Swift 类与结构体(下)
  9. Swift 类的生命周期
  10. Swift 类的初始化器
  11. Swift 类与结构体
  12. OpenGL 压缩纹理
  13. OpenGL 隧道坐标计算
  14. 0penGL 像素格式及数据类型
  15. OpenGL 纹理对象
  16. OpenGL 纹理
  17. OpenGL 模型变化
  18. OpenGL 视图
  19. OpenGL 矩阵
  20. OpenGL 向量
  21. OpenGL 颜色混合
  22. OpenGL 深度测试的潜在风险
  23. OpenGL 浅析深度测试
  24. OpenGL 浅析隐藏面消除
  25. OpenGL 图元连接方式
  26. 记WKWebView与HTML完成交互两三事
  27. OpenGL 渲染流程图解析
  28. OpenGL 控制你的正方形
  29. OpenGL 专业名词解释
  30. OpenGL 环境搭建 - MacOS

上一篇,我们一起探索了 Swift中的Enum, 今天,我们来一起探索下 Swift 中的 Optional。

Optional

认识可选值

之前我们在写代码的过程中早就接触过可选值,比如我们在代码这样定义:

class SMTeacher{
    var age: Int?
}

当前的 实例变量 age 我们就可以称之为可选值,当然可选值的写法这两者是等同的

var age: Int? = var age: Optional<Int>

那么对于 Optional来说 它的本质是什么呢? 我们直接进入到源码中,来打开 Optional.swift 文件,看一下其中的内容。

@frozen
public enum Optional<Wrapped>: ExpressibleByNilLiteral {
    case none
    case some(Wrapped) 
}

通过源码我们可以看到:Optional 的本质是枚举,那么我们当然也可以仿照系统的实现制作一个自己的Optional。

enum SMOptional<Value> { 
    case some(Value)
    case none
}

例如给定任意的一个自然数,如果当前自然数是偶数就返回,否则为 nil,我们应该怎么表达这个案 例呢?

enum SMOptional<Value> { 
    case some(Value)
    case none
}

func getOddValue(_ value: Int) -> MyOptional<Int> {
    if value % 2 == 0 {
        return .some(value) 
    } else {
        return .none
    } 
}
    

如果这个时候给定一个数组,我们想将数组中所有的偶数删除掉:

var array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 
for element in array {
    let value = getOddValue(element)
    array.remove(at: array.firstIndex(of: value)) 
}

这个时候编译器就会检查我们当前的 value 值 会发现它的类型和系统编译器期望的类型并不符合,所以,这个时候我们就能使用 我们的SMOptional类型来限制语法的安全性。

for element in array{
    let value = getOddValue(element) 
    switch value {
        case .some(let value):
            array.remove(at: array.firstIndex(of: value)!) 
        case .none:
            print("vlaue not exist") 
    }
}

除了使用 if let 来处理可选值之外,我们还可以使用 gurad let 来简化我们的代码,我们 来看一个具体的案例

guard letif let 刚好相反,guard let 守护一定有值。如果没有,直接返回。

通常判断是否有值之后,会做具体的逻辑实现,通常代码多。如果用 if let 凭空多了一层分支, guard let 是降低分支层次的办法。