tyr*_*sen 2 struct compiler-optimization rust
Rust书解释了如何使用struct update语法来创建只更新了几个字段的struct的副本.
let mut point = Point3d { x: 0, y: 0, z: 0 };
point = Point3d { y: 1, .. point };
Run Code Online (Sandbox Code Playgroud)
它也不必是相同的结构,可以在创建新结构时使用此语法.
let origin = Point3d { x: 0, y: 0, z: 0 };
let point = Point3d { y: 1, .. origin };
Run Code Online (Sandbox Code Playgroud)
我的问题是关于第二个例子.
如果该origin点永远不会再次使用,编译器是否仍会使(几乎)所有字段的代价变得昂贵(如果字段很大),或者它是否只更新已更新的字段并等同于第一个示例?
如果它就地更新:编译器如何确定它是否可以覆盖origin值?
要回答诸如"编译器是否优化此问题?"之类的问题,我建议您查看反汇编.如果我在编译器资源管理器上编译优化on(-O),请执行以下操作:
pub struct P {
x: i32,
y: i32,
}
pub fn f() -> P {
let mut point = P { x: 43, y: 12 };
point = P { y: 1, ..point };
point
}
Run Code Online (Sandbox Code Playgroud)
我明白了:
push rbp
mov rbp, rsp
movabs rax, 4294967339
pop rbp
ret
Run Code Online (Sandbox Code Playgroud)
如果你知道一点装配,你可以看到没有创建或复制的中间变量.您可以为返回值的初始化添加额外的步骤,并且输出程序集不应更改.
如果删除优化(我不会在此处显示程序集),您可以在程序集中看到编译器首先生成一个,Point { x: 43, y: 12 }然后通过复制x并初始化y为1来创建一个新的.
总结一下:
i32)来自第一个的一些数据来创建另一个点.请注意,您正在链接到Rust 书的第一版,特别是此时已经有近2 年历史的版本。您的链接指向版本 1.6.0 的文档,但 1.23.0 是当前版本。这本书的第二版有不同的措辞。
Rust 书解释了如何使用结构体更新语法来创建结构体的副本
更新语法没有什么特别的。此示例代码仅创建一个副本,因为结构成员(i32在本例中为 )都实现了Copy.
如果原点永远不会再次使用,编译器是否仍会创建字段的 [...] 副本
这完全取决于结构体的值是否实现Copy:
#[derive(Debug)]
struct Coord;
#[derive(Debug)]
struct Point3d { x: Coord, y: Coord, z: Coord }
fn main() {
let origin = Point3d { x: Coord, y: Coord, z: Coord };
let point = Point3d { y: Coord, ..origin };
println!("{:?}", origin);
}
Run Code Online (Sandbox Code Playgroud)
#[derive(Debug)]
struct Coord;
#[derive(Debug)]
struct Point3d { x: Coord, y: Coord, z: Coord }
fn main() {
let origin = Point3d { x: Coord, y: Coord, z: Coord };
let point = Point3d { y: Coord, ..origin };
println!("{:?}", origin);
}
Run Code Online (Sandbox Code Playgroud)
除非实施,否则价值观将被移动Copy。Copy指示编译器应该随意地随意复制类型的位:没有副作用,这样做很有效,并且在语义上是正确的。
如果一个值被移动(即没有实现Copy),那么您之后将无法使用它。
它也不必是相同的结构,在创建新结构时可以使用此语法。
在这两种情况下,您都在创建一个新结构。碰巧的是,在第一种情况下,您碰巧有一个可变绑定,您可以将其放回其中。它实际上相当于:
let point = Point3d { x: 0, y: 0, z: 0 };
let point = Point3d { y: 1, ..point };
Run Code Online (Sandbox Code Playgroud)