Skip to content

32-Option 使用

前言

因为 Option 类型可以同时表示有值和无值两种状态,而无值在某些情况下也可以理解为一种错误,所以 Option 类型也可以用作错

误处理。

示例

javascript
func getString(p: ?Int64): String {
    match (p) {
        case Some(x) => "${x}"
        case None => "none"
    }
}

main() {
    let a = Some(1)
    let b: ?Int64 = None
    let r1 = getString(a)
    let r2 = getString(b)
    println(r1) // 1 
    println(r2) // "none"
}

Option 常用场景

因为 Option 是一种非常常用的类型,所以仓颉为其提供了多种解构方式,以方便 Option 类型的使用。具体包括:模式匹配、错误处理 函数、coalescing 操作符(??),以及问号操作符(?

模式匹配

因为 Option 类型是一种 enum 类型,所以可以使用上文提到的 enum 的模式匹配来实现对 Option 值的解构。例如,下例中函数

getString 接受一个 ?Int64 类型的参数,当参数是 Some 值时,返回其中数值的字符串表示,当参数是 None

时,返回字符串 "none"

javascript
func getString(p: ?Int64): String{
    match (p) {
        case Some(x) => "${x}"
        case None => "none"
    }
}
main() {
    let a = Some(1)
    let b: ?Int64 = None
    let r1 = getString(a)
    let r2 = getString(b)
    println(r1)
    println(r2)
}

getOrThrow 函数

getOrThrow 是 Option包装后的类型的一个函数,它有以下特点,比如 a.getOrThrow()

  1. 如果a是属于Some 类型,那么a.getOrThrow ()返回数据本身
  2. 如果a是属于None类型,那么a.getOrThrow ()抛出异常
javascript
main() {
    let a = Some(1)
    let b: ?Int64 = None
    let r1 = a.getOrThrow()
    println(r1)
    try {
        let r2 = b.getOrThrow()
    } catch (e: NoneValueException) {
        println("b is None")
    }
}

coalescing ??

coalescing /ˌkəʊəˈlesɪŋ/ 联合合并的意思。对于表达式 a??b,如果

  1. a 属于 Some 类型 , 返回a本身
  2. a属于None类型,返回 b
javascript

main() {
    let a = Some(1)
    let b: ?Int64 = None
    let r1: Int64 = a ?? 0 //  r1 = 1 
    let r2: Int64 = b ?? 0 //   r2 = 0
    println(r1) // 1 
    println(r2) // 0 
}

问号操作符 ?

问号操作符 可以理解为是个可选的意思。因为使用了Option包装正常的数据,那么它就有可能会是None,所以在使用了Option包装的数据,想要继续用它内层的属性时,就需要用 ?

javascript
struct R {
    public var a: Int64
    public init(a: Int64) {
        this.a = a
    }
}

main() {
    let r = R(100)
    let x = Some(r) // 等于使用了 Option.Some 来包装了
    let y = Option<R>.None // 等于使用了 Option.Some 来包装了
    let r1 = x?.a // r1 = Option<Int64>.Some(100)
    let r2 = y?.a // r2 = Option<Int64>.None
    println(r1) // Some(100)
    println(r2) // None
}

Released under the MIT License.