跳到主要内容

空安全

Alia 语言提供空安全机制,帮助开发者避免空值错误。

1. Null 与可空类型​

Null 是独立类型,无法参与任何运算(算术、比较、逻辑等);对 Null 值或值为 Null 的变量进行运算会立即报错。typeOf null 返回 'Null'。

使用 ? 后缀声明可空类型,表示该值可以是目标类型或 Null。

基本语法​

<Type?> ~ 可空类型声明

示例​

~ 可空字符串
const name: String? = null
const greeting: String? = 'Hello'

~ 可空数字
const age: Number? = null
const count: Number? = 42

~ 可空对象
const user: Object? = null

~ Null 是独立类型
print typeOf null ~ 输出 'Null'

2. Ok 内置别名​

Ok 是内置别名,用于检查值是否为非空,等价于 typeOf val != 'Null',返回 Boolean。在 assert 等需要显式分组的语境中写作 (Ok val)。

基本语法​

Ok <Value val> ~ 返回 Boolean

示例​

const value1 = 'Hello'
const value2 = null

print Ok value1 ~ 输出 true
print Ok value2 ~ 输出 false

type User *[name: String]
const user: User? = *[name: 'Alice']
if Ok user {
print '用户存在: ' .. user.name
}

assert (Ok value1)

3. 可空参数​

alias 声明中可以使用 <Type? argName> 声明可空参数,允许传入 null。

基本语法​

alias <Type? argName> -> { argName }

示例​

~ 可空字符串参数
alias greet <String? name> -> {
if Ok name {
print 'Hello, ' .. name
} else {
print 'Hello, stranger'
}
}

greet 'Alice' ~ 输出 'Hello, Alice'
greet null ~ 输出 'Hello, stranger'

~ 多个可空参数
alias createUser <String? name> and <Number? age> -> *[name: String, age: Number] {
const realName = name ?? 'Anonymous'
const realAge = age ?? 0
return *[ name: realName, age: realAge ]
}

const u1 = call createUser ['Bob', 25]
print u1.name ~ 输出 'Bob'
print u1.age ~ 输出 25

const u2 = call createUser [null, null]
print u2.name ~ 输出 'Anonymous'
print u2.age ~ 输出 0

~ 混合可空与非可空参数
alias divide <Number a> <Number? b> -> Number {
if Ok b {
if b == 0 { return 0 }
return a / b
} else {
return 0
}
}

print call divide [10, 2] ~ 输出 5
print call divide [10, null] ~ 输出 0

4. 空值合并运算符​

?? 在左侧为 null 时返回右侧的值,否则返回左侧的值。

基本语法​

<Value left> ?? <Value right>

示例​

~ 基本用法
const name = null
const displayName = name ?? '匿名用户'
print displayName ~ 输出 '匿名用户'

const count = 42
const displayCount = count ?? 0
print displayCount ~ 输出 42

~ 链式使用
const value = null ?? null ?? '默认值'
print value ~ 输出 '默认值'

5. 综合示例​

~ 空安全综合示例

~ 1. 可空类型声明
const username: String? = null
const age: Number? = 25

~ 2. 使用 Ok 检查
if Ok username {
print '用户名: ' .. username
} else {
print '用户名为空'
}

~ 3. 使用 ?? 提供默认值
const displayName = username ?? '匿名用户'
print '显示名称: ' .. displayName

~ 4. 嵌套可空对象
type User *[name: String, email: String?]
const bob: User? = *[name: 'Bob', email: 'bob@example.com']
const guest: User? = null

if Ok bob {
print '邮箱: ' .. (bob.email ?? 'default@example.com')
} else {
print '用户为空'
}

const fallback: User = guest ?? *[name: 'Guest', email: null]
print '显示名称: ' .. fallback.name

6. 最佳实践​

6.1 优先使用可空类型​

~ 推荐:明确声明可空返回类型
alias findUser <Number id> -> Object? {
if id > 0 { return *[id: id] }
return null
}

const user: Object? = findUser 1

6.2 使用 ?? 提供合理的默认值​

~ 推荐:提供有意义的默认值
const config = *[timeout: null, retries: null]
const timeout = config.timeout ?? 3000
const retries = config.retries ?? 3

6.3 使用 Ok 进行存在性检查​

~ 推荐:在执行操作前检查值是否存在
const result = null
if Ok result {
print '操作成功: ' .. result
} else {
print '操作失败'
}

下一步​