数字:u8i8u16i16u32i32u64i64u128i128isizeusizef32f64

T 参数&T 参数&mut T 参数T 返回值Option<T> 参数Option<T> 返回值JavaScript 表示
JavaScript 数字或 bigint 值

JavaScript Number 在底层是 64 位浮点值,无法精确表示 Rust 的所有数值类型。wasm-bindgen 将自动使用 BigIntNumber 来精确表示 JavaScript 中 Rust 的数值类型

  • u8i8u16i16u32i32isizeusizef32f64 将在 JavaScript 中表示为 Number
  • u64i64u128i128 将在 JavaScript 中表示为 BigInt

注意:Wasm 目前是 32 位架构,因此 isizeusize 是 32 位整数,并且可以“放入” JavaScript Number

注意u128i128 需要 wasm-bindgen 版本 0.2.96 或更高版本。

从 JavaScript 转换为 Rust

wasm-bindgen 将自动处理 JavaScript 数字到 Rust 数值类型的转换。转换规则如下

Numberu8i8u16i16u32i32isizeusize

如果 JavaScript 数字是 Infinity-InfinityNaN,则 Rust 值将为 0。否则,JavaScript 数字将向零舍入(参见 Math.truncf64::trunc)。如果舍入后的数字对于目标整数类型来说太大或太小,它将环绕。

例如,如果目标类型是 i8,Rust 将看到以下输入值对应的以下值

JS 输入数字Rust 值 (i8)
4242
-42-42
1.9991
-1.999-1
127127
128-128
255-1
2560
-00
±无穷大0
NaN0

这与将 JavaScript Number 赋值给 JavaScript 中相应整数类型的 类型化数组 的行为相同,例如 new Uint8Array([value])[0]

除了对 Infinity-Infinity 的处理外,这与 Rust 中将 f64 强制转换 为相应整数类型的行为相同,例如 value_f64 as u32

BigIntu64i64u128i128

如果 JavaScript BigInt 对于目标整数类型来说太大或太小,它将环绕。

这与将 JavaScript BigInt 赋值给 JavaScript 中 64 位整数类型的 类型化数组 的行为相同,例如 new Int64Array([value])[0]

Numberf32

JavaScript Number 使用与 Rust 中将 f64 强制转换f32 相同的规则转换为 Rust f32,例如 value_f64 as f32

这与 Math.fround 的行为相同,或者将 JavaScript Number 赋值给 JavaScript 中的 Float32Array,例如 new Float32Array([value])[0]

Numberf64

由于 JavaScript 数字是 64 位浮点数值,将 JavaScript Number 转换为 Rust f64 是一个空操作 (no-op)。

Rust 使用示例

#![allow(unused)]
fn main() {
use wasm_bindgen::prelude::*;

#[wasm_bindgen]
pub fn take_number_by_value(x: u32) {}

#[wasm_bindgen]
pub fn return_number() -> f64 {
    42.0
}

#[wasm_bindgen]
pub fn take_option_number(x: Option<u8>) {}

#[wasm_bindgen]
pub fn return_option_number() -> Option<i16> {
    Some(-300)
}
}

JavaScript 使用示例

import {
  take_number_by_value,
  return_number,
  take_option_number,
  return_option_number,
} from './guide_supported_types_examples';

take_number_by_value(42);

let x = return_number();
console.log(typeof x); // "number"

take_option_number(null);
take_option_number(undefined);
take_option_number(13);

let y = return_option_number();
if (y == null) {
  // ...
} else {
  console.log(typeof y); // "number"
}