Skip to content

optional 空值 ​

optional(T) 表示值可以为空。类型修饰写作 kexuan(可选 / optional),空值写作 kong(空 / none):

cpro
bl a leixing kexuan(z32) = kong
bl b leixing kexuan(z32) = 18
cpro
变量 a 类型 可选(i32) = 空
变量 b 类型 可选(i32) = 18
cpro
var a type optional(i32) = none
var b type optional(i32) = 18
  • optional 不能直接参与运算,必须先解包
  • optional 不能嵌套 optional

解包 ​

jiebao(值, 默认值)(解包 / unwrap)取出内部的值;值为空时返回默认值。默认值必须给,且类型要和内部类型一致:

cpro
bl a leixing kexuan(z32) = kong
bl b leixing z32 = 18

bl c = a +[z32] b                   // ✗ 可空值不能直接运算
bl d = jiebao(a, 0) +[z32] b        // ✓ d 是 z32,值为 18
cpro
变量 a 类型 可选(i32) = 空
变量 b 类型 i32 = 18

变量 c = a +[i32] b                 // ✗ 可空值不能直接运算
变量 d = 解包(a, 0) +[i32] b        // ✓ d 是 i32,值为 18
cpro
var a type optional(i32) = none
var b type i32 = 18

var c = a +[i32] b                  // ✗ 可空值不能直接运算
var d = unwrap(a, 0) +[i32] b       // ✓ d 是 i32,值为 18

判空与比较 ​

cpro
ruguo (a == kong) {
    dayin("a 是空的")
} fouze {
    dayin(jiebao(a, 0))
}
cpro
如果 (a == 空) {
    打印("a 是空的")
} 否则 {
    打印(解包(a, 0))
}
cpro
if (a == none) {
    print("a 是空的")
} else {
    print(unwrap(a, 0))
}

两个 optional 可以直接比较(都为空,或都有值且值相等),但只限内部是数字、zhenjia(bool)、zifu(rune)这类简单类型。内部是字符串、数组、结构体时,先判空再解包比较:

cpro
bl s1 leixing kexuan(zifuchuan) = "a"
bl s2 leixing kexuan(zifuchuan) = "b"

ruguo (s1 == s2) { }                                     // ✗ 内部是 zifuchuan,不能直接比较
ruguo (s1 == kong) { }                                   // ✓ 和空值比较不受限制
ruguo (jiebao(s1, "") ==[zifuchuan] jiebao(s2, "")) { }  // ✓
cpro
变量 s1 类型 可选(string) = "a"
变量 s2 类型 可选(string) = "b"

如果 (s1 == s2) { }                                 // ✗ 内部是 string,不能直接比较
如果 (s1 == 空) { }                                 // ✓ 和空值比较不受限制
如果 (解包(s1, "") ==[string] 解包(s2, "")) { }     // ✓
cpro
var s1 type optional(string) = "a"
var s2 type optional(string) = "b"

if (s1 == s2) { }                                   // ✗ 内部是 string,不能直接比较
if (s1 == none) { }                                 // ✓ 和空值比较不受限制
if (unwrap(s1, "") ==[string] unwrap(s2, "")) { }   // ✓

作参数、返回值与字段 ​

cpro
hs foo(a kexuan(z32)) z32 {
    fanhui jiebao(a, 0)
}

hs bar() kexuan(z32) {
    fanhui kong
}

jiegouti Person {
    name leixing zifuchuan,
    age  leixing kexuan(z64),
}

rukou() {
    bl p leixing Person = { name: "张三", age: 18 }  // 18 自动包装
    dayin(jiebao(p.age, 0))
}
cpro
函数 foo(a 可选(i32)) i32 {
    返回 解包(a, 0)
}

函数 bar() 可选(i32) {
    返回 空
}

结构体 Person {
    name 类型 string,
    age  类型 可选(i64),
}

入口() {
    变量 p 类型 Person = { name: "张三", age: 18 }  // 18 自动包装
    打印(解包(p.age, 0))
}
cpro
fn foo(a optional(i32)) i32 {
    return unwrap(a, 0)
}

fn bar() optional(i32) {
    return none
}

struct Person {
    name type string,
    age  type optional(i64),
}

rukou() {
    var p type Person = { name: "张三", age: 18 }   // 18 自动包装
    print(unwrap(p.age, 0))
}

不可拷贝的结构体 不能放进 optional。

cpro 目前处于测试阶段