type_system

SKILL.md

仓颉语言类型系统 Skill

1. 类型系统概述

  • 仓颉是静态类型语言,支持子类型多态
  • 若参数/变量/返回类型为 T,可接受 T 的任何子类型
  • 仓颉不支持不同类型之间的隐式转换(子类型到父类型不被视为"转换")

2. 子类型关系

2.1 子类型关系来源

  1. 类继承class Sub <: Super {}Sub <: Super
  2. 接口实现(含扩展实现):类型实现接口后成为接口的子类型
  3. 元组类型(协变,逐元素):(C2, C4) <: (C1, C3)C2 <: C1C4 <: C3
  4. 函数类型(参数逆变,返回协变):(U1) -> S2 <: (U2) -> S1 当且仅当 U2 <: U1S2 <: S1
  5. 恒真关系
    • T <: T(自反性)
    • Nothing <: T 对所有 T 成立
    • T <: Any 对所有 T 成立
    • C <: Object 对任何 class C 成立
  6. 传递性:若 A <: BB <: C,则 A <: C

2.2 泛型类型的子类型关系

  • 根据泛型定义中的继承声明确定,如 class C<Z> <: I<Z, Z> {}C<Bool> <: I<Bool, Bool>
  • 用户定义的泛型类型在类型参数处默认不型变(详见下文型变规则)

3. 型变规则(Variance)

3.1 定义

AB 为类型,T 为类型构造器(含一个类型参数 X):

型变 条件 说明
不型变(invariant) T<A> <: T<B> 当且仅当 A = B 用户定义的泛型类型默认行为
协变(covariant) T<A> <: T<B> 当且仅当 A <: B 内建元组类型对每个元素协变
逆变(contravariant) T<A> <: T<B> 当且仅当 B <: A 内建函数类型在参数处逆变

3.2 仓颉中的规则

  • 用户自定义泛型类型:在所有类型变元处不型变
    • 例:给定 interface I<X>D <: CI<D> <: I<C> 不成立
    • 仅当 A = B 时,I<A> <: I<B> 才成立
  • 内建元组类型:对每个元素类型协变
  • 内建函数类型:入参类型处逆变,返回类型处协变

注意class 以外的类型实现接口,该类型和该接口之间的子类型关系不能作为协变和逆变的依据。


4. 类型转换

4.1 无隐式转换

  • 仓颉无隐式类型转换(子类型到父类型不被视为"转换")
  • 所有类型转换须显式进行

4.2 数值转换

  • T(e) 其中 Te 为任意数值类型(Int8/Int16/Int32/Int64/IntNative/UInt8/UInt16/UInt32/UInt64/UIntNative/Float16/Float32/Float64
  • 可能溢出:编译时检测 → 错误;运行时 → 异常

4.3 Rune ↔ 整数转换

  • UInt32(runeExpr) — 返回 Unicode 标量值
  • Rune(intExpr) — 仅当值在 [0x0000, 0xD7FF][0xE000, 0x10FFFF] 范围内有效;否则编译报错或运行时抛异常

4.4 is 运算符

  • e is TBool。当 e运行时类型T 的子类型时返回 true
let b: Base = Derived()
b is Derived  // true
b is Base     // true

4.5 as 运算符

  • e as TOption<T>。运行时类型是子类型时返回 Some(e),否则返回 None
  • 安全向下转型机制 — 无异常,仅返回 Option
let b: Base = Derived()
b as Derived  // Option<Derived>.Some(b)
b as String   // Option<String>.None

5. 类型别名

5.1 声明

  • 关键字:type
  • 语法:type Alias = OriginalType
  • 不创建新类型 — 仅为替代名称

5.2 规则

  1. 仅限顶层 — 不能在函数内定义
  2. 原始类型须在别名定义处可见
  3. 不允许循环引用 — 直接或间接循环均禁止

5.3 使用场景

  1. 作为类型var a: A = B() 其中 type A = B
  2. 作为构造函数(当别名指向 class/struct 时):A() 构造 B
  3. 访问静态成员A.foo()A.b
  4. 访问枚举构造函数Time.Day 其中 type Time = TimeUnit

5.4 限制

  • 用户自定义类型别名不能用于类型转换表达式

5.5 泛型类型别名

  • 类型别名可声明类型参数
  • 不能对别名类型参数使用 where 约束
type RD<T> = RecordData<T>
Weekly Installs
3
First Seen
4 days ago
Installed on
opencode2
gemini-cli2
claude-code2
github-copilot2
codex2
kimi-cli2