Rust位置表达式和值表达式

发布于:2025-09-10 ⋅ 阅读:(23) ⋅ 点赞:(0)

Rust 里把表达式分为两类:

位置表达式 (place expression) —— 表示一个内存位置,可以作为赋值语句的左值。

值表达式 (value expression) —— 表示一个具体的值,只能作为右值。


1. 本地变量 (Local Variables)

本地变量本身就是位置表达式,可以存储和修改值。

fn main() {
    let mut x = 10; // x 是位置表达式
    x = 20;         // 可以赋值,因为 x 是一个内存位置
    println!("{}", x);
}

2. 静态变量 (Static Variables)

静态变量有固定的内存位置,所以也是位置表达式。

static mut COUNTER: i32 = 0;

fn main() {
    unsafe {
        COUNTER = 100;  // 静态变量是位置表达式
        println!("{}", COUNTER);
    }
}

3. 解引用 (*expr)

对指针解引用后得到的是一个位置(指向的内存)。


fn main() {
    let mut x = 10;
    let y = &mut x;
    *y = 20;     // *y 是位置表达式,表示 x 的位置
    println!("{}", x);
}


4. 数组索引 (expr[expr])

数组或切片的索引表达式是位置表达式。

fn main() {
    let mut arr = [1, 2, 3];
    arr[0] = 10;  // arr[0] 是位置表达式
    println!("{:?}", arr);
}

5. 字段引用 (expr.field)

结构体的字段是位置表达式。

struct Point { x: i32, y: i32 }

fn main() {
    let mut p = Point { x: 0, y: 0 };
    p.x = 10;    // ✅ p.x 是位置表达式
    println!("({}, {})", p.x, p.y);
}

6. 位置表达式组合

比如 arr[0].field(*ptr).fieldstruct.field[index] 之类的组合,依然是位置表达式。

struct Item { val: i32 }

fn main() {
    let mut arr = [Item { val: 1 }, Item { val: 2 }];
    arr[1].val = 99;  // ✅ arr[1].val 是位置表达式
    println!("{}", arr[1].val);
}

注意事项:
值表达式不能出现在位置上下文中

pub fn temp() -> i32 {
    return 1;

}

fn main() {
    let x = &temp();
    temp() = *x; //错误
}

其中&temp()表示获取temp()返回的临时变量的地址


当位置表达式出现在值上下文中时,该位置表达式将会把内存地址转移给另外一个位置
表达式,这其实是所有权的转移,如

fn main() {
    let a = "hello";             // a 的类型是 &str,字符串字面量,存储在静态区,不涉及所有权转移
    let b = "hello".to_string(); // b 的类型是 String,堆上分配内存,拥有所有权

    let ohter = a;               // &str 可以 Copy,所以 a 依然可用
    println!("{:?}", ohter);

    let ohter = b;               // String 没有实现 Copy,赋值时发生 move,b 的所有权转移给 ohter
    println!("{:?}", ohter);

    // println!("{}",a);          // 正确 a 还能用,因为 a 没有被 move,只是复制了个指针
    // println!("{}",b);          // 错误,因为 b 的所有权已经被转移走,b 无效
}


网站公告

今日签到

点亮在社区的每一天
去签到