为什么允许以下代码段中的赋值?

#[derive(Copy, Clone)]
pub struct X {
    pub a: u8,
}

fn main() {
    let x = X { a: 0 };
    { x }.a = 5;
    assert!(x.a == 5); // I was wrong
}

我是否分配给临时工?

尽管这些是禁止的:

({ x.a }) = 5;
let mut y: u8 = 0;
({ y }) = 5;

我问,因为我有一只虫子

unsafe { *some_struct }.mem1 = 5;

我没有使用

unsafe { *some_struct.mem1 = 5; }

从一开始,因为让不安全的区块尽可能短是正确的.

推荐答案

我试图尽可能简化最初的示例.

第一次try 111是很正常的;没什么可说的了.

第二次try 使用2是完全无用的,因为创建的临时对象在创建后立即消失(没有副作用,这可能是

第三次try 使用333甚至比前一次更无用,因为我们在它消失之前改变了临时性(没有更多的副作用,这可能会得到优化).

第四次try 444与问题直接相关.

赋值运算符的左侧必须是位置表达式.位置表达式表示内存位置,可以是变量(具有可选名称空间)、解引用、索引表达式或字段引用.

The Rust Reference的第Place Expressions and Value Expressions节也有类似的内容,但有更多的细节.

因此,关于第三次try 和第四次try 之间的差异的原始答案仅仅在于,第三次try 的现场参考被视为place expression.

然而,我并不觉得这个答案很令人满意,因为我不知道语言设计师在这个 Select 中的动机.

struct X {
    a: u8,
}
fn main() {
    let mut _x = X { a: 1 };
    _x = X { a: 11 };

    X { a: 2 }; // created, then dropped straight away

    X { a: 3 }.a = 33; // created, altered, then dropped straight away

    // X { a: 4 } = X { a: 44 }; // fails with error E0070
}

Rust相关问答推荐

即使参数和结果具有相同类型,fn的TypId也会不同

go 掉包装 struct 中的泛型

什么时候铁 rust FFI边界上的panic 是未定义的行为?

在Rust中宏的表达式中提取对象

在析构赋值中使用一些现有绑定

在使用#[NO_STD]时,如何在Rust中收到紧急消息?

失真图像图形捕获Api

Rust从关联函数启动线程

为什么HashMap::get和HashMap::entry使用不同类型的密钥?

期望一个具有固定大小 x 元素的数组,找到一个具有 y 元素的数组

如何将一个矩阵的列分配给另一个矩阵,纳尔代数?

一次不能多次borrow *obj作为可变对象

当推送到 HashMap 中的 Vector 时,类型 `()` 无法取消引用

如何使用 Bincode 在 Rust 中序列化 Enum,同时保留 Enum 判别式而不是索引?

如何在 Rust 中将 Vec> 转换为 Vec>?

当用作函数参数时,不强制执行与绑定的关联类型

制作嵌套迭代器的迭代器

如果返回类型是通用的,我可以返回 &str 输入的一部分吗?

在传输不可复制的值时实现就地枚举修改

Rust:为什么在 struct 中borrow 引用会borrow 整个 struct?