使用此代码:
struct Point {
x: f64,
y: f64,
}
struct Rectangle {
p1: Point,
p2: Point,
}
impl Rectangle {
pub fn new(x1: f64, y1: f64, x2: f64, y2: f64) -> Rectangle {
let r = Rectangle {
p1: Point { x: x1, y: y1 },
p2: Point { x: x2, y: y2 },
};
// some code where r is used
r
}
}
let rectangle = Rectangle::new(0.0, 0.0, 10.0, 10.0);
从内存的角度来看,rectangle
是与r
相同的实例,还是r
的副本?
我是否必须通过引用显式返回(类似&r
)?
我必须创造数百万个矩形,我不希望那里有无用的副本。
答案 0 :(得分:14)
从内存的角度来看,
rectangle
是与r
相同的实例,还是r
的副本?
<强>未指定的强>
Rust语言指定了语言的语义,虽然它们在某种程度上限制了实现,但在这种情况下却没有。如何将返回值传递给调用堆栈是 ABI 的一部分,不仅ABI不稳定(在Rust中),它也是特定于平台的。
我是否必须通过引用显式返回(类似
&r
)?
Returning by reference is not possible
您可以返回Box<Rectangle>
,但内存分配的成本会使首先复制Rectangle
的成本相形见绌,因此这是不可取的。
您可以使用输出参数强制执行此操作,但这还有其他问题:
&mut Rectangle
参数,首先需要有一个有效的实例,必须初始化;相当浪费,*mut Rectangle
指向未初始化的内存,则需要使用unsafe
代码,几乎不满意。...然而
我必须创造数百万个矩形,我不希望那里有无用的副本。
我认为你无所畏惧。
性能调优的第一条规则是先测量;而且我怀疑你是否能够在数百万个矩形的创建中观察到性能问题。
编译器有多个技巧,例如:
rectangle
实例开始,而是通过CPU寄存器传递其组件,new
,避免任何副本,因此,在担心复制4 f64
的成本之前,我会实现天真的解决方案,在发布模式下编译,并观察会发生什么。