# 类型

¥Types

AssemblyScript 继承了 WebAssembly 更具体的整数、浮点和引用类型:

¥AssemblyScript inherits WebAssembly's more specific integer, floating point and reference types:

AssemblyScript 类型 WebAssembly 类型 TypeScript 类型 描述
整数类型
i32 i32 数字 32 位有符号整数。
u32 i32 数字 32 位无符号整数。
i64 i64 大整数 64 位有符号整数。
u64 i64 大整数 64 位无符号整数。
isize i32 或 i64 数字或 bigint WASM32 中的 32 位有符号整数。
WASM64 中的 64 位有符号整数🦄。
usize i32 或 i64 数字或 bigint WASM32 中的 32 位无符号整数。
WASM64 中的 64 位无符号整数🦄。
浮点类型
f32 F32 数字 32 位浮点数。
f64 f64 数字 64 位浮点数。
小整数类型
i8 i32 数字 8 位有符号整数。
u8 i32 数字 8 位无符号整数。
i16 i32 数字 16 位有符号整数。
u16 i32 数字 16 位无符号整数。
bool i32 布尔值 1 位无符号整数。
矢量类型
v128 v128 * 128 位向量。
参考/GC 类型
ref_extern (参考外部) 对象 外部参考。
ref_func (参考函数) 函数 函数参考。
ref_any (参考任何) 对象 内部参考。🦄
ref_eq (参考方程) 对象 一个可等价的参考。🦄
ref_struct (参考结构) 对象 一个数据参考。🦄
ref_array (参考数组) 数组 数组引用。🦄
ref_string (参考字符串) 字符串 字符串引用。🦄
ref_stringview_wtf8 (参考 stringview_wtf8) * WTF-8 字符串视图参考。🦄
ref_stringview_wtf16 (参考 stringview_wtf16) 字符串 WTF-16 字符串视图参考。🦄
ref_stringview_iter (参考 stringview_iter) * 字符串迭代器引用。🦄
特殊类型
void * 空白 表示无返回值。

注意

上面的基本引用类型是不可为空的。根据规范,规范别名也可用,并引用相应的可为空类型,例如 Wasm 中 type externref = ref_extern | null 映射到 externref == (ref null extern)ref_ 前缀暂时避免命名冲突,将来可能会被删除。

¥The base reference types above are non-nullable. Canonical aliases, as per the spec, are available as well and refer to the respective nullable type, e.g. type externref = ref_extern | null mapping to externref == (ref null extern) in Wasm. The ref_ prefix avoids naming collisions for the time being and might be dropped in the future.

就像在 TypeScript 中一样,类型在变量、函数参数或类成员名称之后进行注释,并用 : 分隔,如下所示:

¥Just like in TypeScript, types are annotated after variable, function argument or class member names, separated by :, like so:

function add(a: i32, b: i32): i32 {
  let sum: i32 = a + b; // type can be inferred, annotation can be omitted
  return sum;
}

# 类型规则

¥Type rules

当编译器看到实际上可能不是预期的隐式转换时,它会抗诉,这与 C 编译器的做法非常相似。

¥The compiler will complain when it sees an implicit conversion that might not actually be intended, quite similar to what a C compiler would do.

# 铸件

¥Casting

在 AssemblyScript 中,TypeScript 中已知的类型断言 <T>expressionexpression as T 成为显式类型转换,本质上告诉编译器该转换是有意的。此外,上面提到的每个类型名称,除了别名之外,还充当可移植转换内置函数,可以像 i32(expression) 一样使用。在使用 TypeScript 编译器 (see) 将完全相同的代码编译为 JavaScript 的情况下,使用可移植转换特别有用,否则需要插入像 expression | 0 这样的 asm.js 样式类型强制转换。

¥In AssemblyScript, the type assertions <T>expression and expression as T known from TypeScript become explicit type conversions, essentially telling the compiler that the conversion is intended. In addition, each of the type names mentioned above, except aliases, also act as portable conversion built-ins that can be used just like i32(expression). Using portable conversions is especially useful where the exact same code is meant to be compiled to JavaScript with the TypeScript compiler (see), that otherwise would require the insertion of asm.js-style type coercions like expression | 0.

# 推断

¥Inference

与 TypeScript 相比,AssemblyScript 中的类型推断受到限制,因为必须提前知道每个表达式的类型。这意味着变量和参数声明必须具有其类型注释或具有初始值设定项。如果没有类型注释且只有初始值设定项,AssemblyScript 将首先假定 i32,并且只有在该值不适合(变成 i64)、是浮点数(变成 f64)或无可辩驳地具有除这些类型之外的其他类型(例如类型)时才重新考虑其他类型 变量的返回类型、函数的返回类型或类类型。此外,函数必须用返回类型进行注释,以帮助编译器做出正确的决定,例如返回字面量或存在多个返回语句。

¥Compared to TypeScript, type inference in AssemblyScript is limited because the type of each expression must be known in advance. This means that variable and parameter declarations must either have their type annotated or have an initializer. Without a type annotation and only an initializer, AssemblyScript will assume i32 at first and only reconsider another type if the value doesn't fit (becomes i64), is a float (becomes f64) or irrefutably has another type than these, like the type of a variable, the return type of a function or a class type. Furthermore, functions must be annotated with a return type to help the compiler make the correct decisions, for example where a literal is returned or multiple return statements are present.

# 可空性

¥Nullability

基本类型不能为 null,但类和函数类型可以。附加 | null 声明可为 null 的类型。

¥Basic types cannot be nullable, but class and function types can. Appending | null declares a nullable type.

# 可分配性

¥Assignability

将一种类型的值分配给另一种类型的目标无需显式转换即可执行,其中可以在目标类型中表示全部可能值,而不管解释/符号性如何:

¥Assigning a value of one type to a target of another type can be performed without explicit casts where the full range of possible values can be represented in the target type, regardless of interpretation/signedness:

布尔值 i8/u8 i16/u16 i32/u32 i64/u64 F32 f64
布尔值
i8/u8
i16/u16
i32/u32
i64/u64
F32
f64

请注意,isizeusize 是 WASM32 中 i32u32 的别名,分别是 WASM64 中 i64u64 的别名。

¥Note that isize and usize are aliases of either i32 and u32 in WASM32 respectively i64 and u64 in WASM64 🦄.

var  i8val: i8  = -128  // 0x80
var  u8val: u8  = i8val // becomes 128 (0x80)
var i16val: i16 = i8val // becomes -128 through sign-extension (0xFF80)
var u16val: u16 = i8val // becomes 65408 through masking (0xFF80)
var f32val: f32 = i8val // becomes -128.0

Wasm 参考和 GC 类型预计遵循以下层次结构 🦄:

¥Wasm reference and GC types are anticipated to adhere to the following hierarchy 🦄:

Diagram of anticipated reference types hierarchy.

虚线元素未暴露和/或不清楚。(...)-占位符表示具体的子类型,例如 特定元素类型的数组、具有特定字段类型和潜在超类型的结构,或者具有特定参数和返回类型的函数。详情参见 Wasm GC 的子类型规则 (opens new window)

¥Dashed elements are not exposed and/or unclear. (...)-placeholders indicate the concrete subtypes, e.g. an array of a specific element type, a struct with specific field types and potentially a supertype, or a function with specific parameter and return types. For details, see Wasm GC's subtyping rules (opens new window).

# 可比性

¥Comparability

可以根据上面可分配性中概述的相同规则来比较不同类型的两个值,而无需显式转换

¥Comparing two values of different types can be performed without an explicit cast under the same rules as outlined in assignability above

  1. 如果比较是绝对的(=====!=!==

    ¥if the comparison is absolute (== or ===, != or !==)

  2. 如果比较是相对的(><>=<=)并且两种类型具有相同的符号

    ¥if the comparison is relative (>, <, >=, <=) and both types have the same signedness

因为 WebAssembly 对于有符号和无符号比较有不同的操作。比较使用较大的类型并返回 bool

¥because WebAssembly has distinct operations for signed and unsigned comparisons. The comparison uses the larger type and returns bool.

请注意,===== 分别是 !=!== 在 AssemblyScript 中是相同的,因为在其严格的类型规则下,比较两个不同类型的值是无效的。

¥Note that == and === respectively != and !== are the same in AssemblyScript because comparing two values of different types is invalid under its strict typing rules anyhow.

# 位移位

¥Bit shifts

位移位(<<>>)的结果是左类型,右类型隐式转换为左类型,如果左类型有符号则执行算术移位,如果左类型无符号则执行逻辑移位。

¥The result of a bit shift (<<, >>) is the left type, with the right type implicitly converted to the left type, performing an arithmetic shift if the left type is signed and a logical shift if the left type is unsigned.

无符号右移 (>>>) 的结果是左类型(保留符号性),右类型隐式转换为左类型,但始终执行逻辑移位。

¥The result of an unsigned right shift (>>>) is the left type (signedness is retained), with the right type implicitly converted to the left type, but always performing a logical shift.

请注意,只有移位的 log2(sizeof<T>()) 个最低有效位会影响结果:

¥Note that only the log2(sizeof<T>()) least significant bits of the shift affect the result:

类型 有效位 示例
i8/u8 3 x << yx << (y & 7)
i16/u16 4 x << yx << (y & 15)
i32/u32 5 x << yx << (y & 31)
i64/u64 6 x << yx << (y & 63)

如果左侧类型是浮点数,则会触发错误。

¥If the left type is a float, an error is emitted.

# 宏类型

¥Macro types

以下宏类型提供对否则无法获取的相关类型的访问。

¥The following macro types provide access to related types that would otherwise be impossible to obtain.

宏型 描述
native<T> 获取 T 的底层原生类型,例如 如果 T 是一个类(在 WASM32 中),则为 u32
indexof<T> 根据索引访问过载获取集合的索引类型。
valueof<T> 根据索引访问过载获取集合的值类型。
returnof<T> 获取函数类型的返回类型。

# 范围限制

¥Range limits

为了方便起见,特定于 WebAssembly 类型的各种范围限制作为全局常量存在:

¥Various range limits specific to the WebAssembly types are present as global constants for convenience:

  • const i8.MIN_VALUE: i8 = -128
    const i8.MAX_VALUE: i8 = 127
    
  • const i16.MIN_VALUE: i16 = -32768
    const i16.MAX_VALUE: i16 = 32767
    
  • const i32.MIN_VALUE: i32 = -2147483648
    const i32.MAX_VALUE: i32 = 2147483647
    
  • const i64.MIN_VALUE: i64 = -9223372036854775808
    const i64.MAX_VALUE: i64 = 9223372036854775807
    
  • const isize.MIN_VALUE: isize // WASM32: i32.MIN_VALUE, WASM64: i64.MIN_VALUE
    const isize.MAX_VALUE: isize // WASM32: i32.MAX_VALUE, WASM64: i64.MAX_VALUE
    
  • const u8.MIN_VALUE: u8 = 0
    const u8.MAX_VALUE: u8 = 255
    
  • const u16.MIN_VALUE: u16 = 0
    const u16.MAX_VALUE: u16 = 65535
    
  • const u32.MIN_VALUE: u32 = 0
    const u32.MAX_VALUE: u32 = 4294967295
    
  • const u64.MIN_VALUE: u64 = 0
    const u64.MAX_VALUE: u64 = 18446744073709551615
    
  • const usize.MIN_VALUE: usize = 0
    const usize.MAX_VALUE: usize // WASM32: u32.MAX_VALUE, WASM64: u64.MAX_VALUE
    
  • const bool.MIN_VALUE: bool = 0
    const bool.MAX_VALUE: bool = 1
    
  • const f32.MIN_VALUE: f32 = -3.40282347e+38
    const f32.MAX_VALUE: f32 = 3.40282347e+38
    const f32.MIN_NORMAL_VALUE: f32 = 1.17549435e-38
    const f32.MIN_SAFE_INTEGER: f32 = -16777215
    const f32.MAX_SAFE_INTEGER: f32 = 16777215
    const f32.EPSILON: f32 = 1.19209290e-07
    
  • const f64.MIN_VALUE: f64 = -1.7976931348623157e+308
    const f64.MAX_VALUE: f64 = 1.7976931348623157e+308
    const f64.MIN_NORMAL_VALUE: f64 = 2.2250738585072014e-308
    const f64.MIN_SAFE_INTEGER: f64 = -9007199254740991
    const f64.MAX_SAFE_INTEGER: f64 = 9007199254740991
    const f64.EPSILON: f64 = 2.2204460492503131e-16