optional 空值
optional(T) 表示值可以为空。类型修饰写作 kexuan(可选 / optional),空值写作 kong(空 / none):
cpro
bl a leixing kexuan(z32) = kong
bl b leixing kexuan(z32) = 18cpro
变量 a 类型 可选(i32) = 空
变量 b 类型 可选(i32) = 18cpro
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,值为 18cpro
变量 a 类型 可选(i32) = 空
变量 b 类型 i32 = 18
变量 c = a +[i32] b // ✗ 可空值不能直接运算
变量 d = 解包(a, 0) +[i32] b // ✓ d 是 i32,值为 18cpro
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。
