后浪笔记一零二四

在 Rust 中,​​Hygienic Macros(卫生宏)​​ 是语言设计的一个重要特性,它确保了宏展开时不会意外地捕获或污染调用者作用域中的变量,从而避免了名称冲突和不可预期的行为。

Rust 的卫生宏(Hygienic Macros)主要通过 ​语法上下文(Syntax Context)​​ 和 ​​ExpnId​​ 来实现。编译器会为每个宏展开分配一个唯一的扩展 ID(ExpnId),并跟踪标识符的来源和绑定关系。

需要注意的点:

  • 并非绝对卫生​​:Rust 的 macro_rules! 宏在局部变量和标签上是卫生的,但对于其他项(如函数、模块、 trait 等)可能并非完全卫生。例如,宏中引用的外部函数或类型仍需在调用处可见。
  • ​过程宏(Procedural Macros)​​ 默认是​​非卫生​​的(Unhygienic)。过程宏的作者需要自行处理标识符的生成和解析,以避免名称冲突。这意味着编写过程宏时需要更小心。
  1. 变量

rust通过静态类型来保证类型安全,使用let关键字来绑定变量类型:

fn main() {
    let x: i32 = 10;
    println!("x: {x}");
    // x = 20;  // 这里会报错: cannot assign twice to immutable variable
    // println!("x: {x}");
}

以下是基本的内置类型及其字面量

类型 字面量
有符号整数 i8,i16,i32,i64,i128,isize -10, 0, 1_1000, 123_i64
无符号整数 u8,u16,u32,u64,u128,usize 0, 123, 10_u16
浮点数 f32, f64 3.14, -10.0e20, 2_f32
Unicode标量 char ‘a’, ‘α’, ‘∞’
布尔值 bool true, false

各类型占用的空间为:

  • iN, uN 和 fN 占用 N 位,
  • isize 和 usize 占用一个指针大小的空间,
  • char 占用 32 位空间,
  • bool 占用 8 位空间。

char为何是32位:Unicode 标量值的最大码位是 U+10FFFF。要无损地表示所有这些可能的值,至少需要 21 位。Rust 选择 32 位(4 字节)来确保 char 类型有​​充足的空间​​容纳任何 Unicode 字符。

char 表示的是 Unicode 码位,它在内存中固定占用 4 字节。而当 char 被存入字符串(如 String 或 &str)时,Rust 会使用 ​​UTF-8​​ 编码。在 UTF-8 编码下,一个字符可能占用 ​​1 到 4 个字节。char 的 len_utf8() 方法可以查看其 UTF-8 编码的字节长度。

bool 类型为何是 8 位?​​:这主要是为了​​内存对齐​​和​​访问效率​​。

  • 现代 CPU 通常以​​字节​​(8 位)为最小单位进行内存访问。如果只分配 1 位,编译器可能需要生成更复杂的指令来提取和操作特定位,这可能反而会降低效率。
  • 直接操作一个字节通常比提取一个位更高效。如果 bool 占 1 位,要读取它的值,CPU 可能需要先读取包含它的整个字节(或字),然后进行位掩码和移位操作才能得到那 1 位的值。直接读取一个字节则省去了这些步骤。
  • 虽然在单独处理时 bool 占 1 字节,但当 bool 作为结构体或枚举的一部分时,Rust 编译器会尝试进行​​位级优化​​(例如 Option)。编译器可能会将多个 bool 字段打包到同一个字节中,以节省内存。
  1. 类型推导

Rust 会根据变量的使用来确定其类型:

fn takes_u32(x: u32) {
    println!("u32: {x}");
}

fn takes_i8(y: i8) {
    println!("i8: {y}");
}

fn main() {
    let x = 10;
    let y = 20;

    takes_u32(x);
    takes_i8(y);
    // takes_u32(y);
}

整型默认推导为 i32, 浮点型默认推导为f64


本文发表于 0001-01-01,最后修改于 0001-01-01。

本站永久域名「 jiavvc.top 」,也可搜索「 后浪笔记一零二四 」找到我。


上一篇 « 下一篇 »

赞赏支持

请我吃鸡腿 =^_^=

i ysf

云闪付

i wechat

微信

推荐阅读

Big Image