是否移动了返回值?

bar*_*can 2 rust

使用此代码:

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);
Run Code Online (Sandbox Code Playgroud)

从内存的角度来看,是rectangle同一个实例r,还是它的副本r

我是否必须通过引用明确返回(类似的东西&r)?

我必须创建数百万个矩形,我不希望有无用的副本.

Mat*_* M. 14

从内存的角度来看,是rectangle同一个实例r,还是它的副本r

未指定.

Rust语言指定了语言的语义,虽然它们在某种程度上限制了实现,但在这种情况下它们却没有.如何将返回值传递给调用堆栈是ABI的一部分,不仅ABI不稳定(在Rust中),它也是特定于平台的.

我是否必须通过引用明确返回(类似的东西&r)?

无法通过引用返回.

你可以返回一个,Box<Rectangle>但内存分配的成本会使复制a的成本相形见绌Rectangle,所以这是不可取的.

您可以使用输出参数强制执行此操作,但这还有其他问题:

  • 如果你有一个&mut Rectangle参数,你首先需要有一个有效的实例,必须初始化; 相当浪费
  • 如果你*mut Rectangle指向未初始化的内存,你需要使用unsafe代码,几乎不满意.

然而...

我必须创建数百万个矩形,我不希望有无用的副本.

我觉得你什么都不担心.

性能调优的第一条规则是先测量 ; 而且我怀疑你是否能够在创造数百万个矩形时观察到性能问题.

编译器有多个技巧,例如:

  • 甚至没有rectangle实现开始的实例,而是通过CPU寄存器传递其组件,
  • new在呼叫站点内联,避免任何副本,
  • ...

因此,在担心复制4的成本之前f64,我会实现天真的解决方案,在发布模式下编译,并观察会发生什么.