按值传递指针的组件
Passing a component of a pointer by value
我刚开始接触 Rust,所以我的一些概念可能是错误的。如果是这种情况,我将不胜感激。
我正在关注 lifetimes guide 并尝试了一些示例。我稍微修改了矩形示例。
我更改了 compute_distance
函数以在第一个参数中按值接受 Point
。
然后我在 compute_distance
.
的调用中删除了 on_the_stack.origin
之前的 &
这给了我以下错误:
cannot move out of dereference of &
-pointer
如果我在 on_the_stack.origin
调用之前添加 &
并在 compute_distance
函数中通过引用接受 Point
,它会顺利运行。
第二种方法对我来说很有意义,但为什么我原来的方法会抛出错误?
use std::num::Float;
struct Point {
x : f64,
y : f64
}
struct Size {w: f64, h: f64}
struct Rectangle {origin: Point, size: Size}
#[cfg(not(test))]
fn main() {
let on_the_stack = &Rectangle{origin: Point {x: 1.0, y: 2.0},
size: Size {w: 3.0, h: 4.0}};
let on_the_heap = box Rectangle {origin: Point {x: 5.0, y: 6.0},
size: Size {w: 3.0, h: 4.0}};
println!("Distance: {}", compute_distance(on_the_stack.origin,&on_the_heap.origin));
}
fn compute_distance ( p1:Point,p2:&Point) -> f64 {
let x_d = p1.x - p2.x;
let y_d = p1.y - p2.y;
Float::sqrt(x_d * x_d + y_d * y_d)
}
如您所说,您更改后的 compute_distance
需要 value 作为第一个参数。这意味着该函数将取得参数的所有权。
但是,您正试图传递结构的一小部分(origin
嵌入在 Rectangle
中)。为此,Rust 必须将 Rectangle
的 部分 的所有权赋予该方法,但 Rectangle
究竟会处于什么状态?一个非常破损的,所以 Rust 会阻止你这样做。耶,你没有搬起石头砸自己的脚!
"But wait",你说,"it's totally cool if the function gets a copy of origin
"。作为人类,您可以识别并告诉编译器它是 "totally cool":
#[deriving(Copy)]
struct Point { /* ... */ }
现在 Rust 知道,如果愿意,可以安全地逐位复制 Point
。万岁!
"But wait",你说,"what if it's not cool to make a bit-for-bit copy? My structure needs more love than being treated like a bag of bits!"。同样,作为一个聪明的人,你可以表达:
#[deriving(Clone)]
struct Point { /* ... */ }
// later...
on_the_stack.origin.clone()
现在您可以进行显式调用 (clone()
) 以获取选项的语义副本。因为这可能是一项昂贵的操作,所以编译器不会为您完成。
关于 deriving
的注释
在我写这个答案时,deriving
正在过渡到 derive
。根据您的代码需要进行调整。
我刚开始接触 Rust,所以我的一些概念可能是错误的。如果是这种情况,我将不胜感激。
我正在关注 lifetimes guide 并尝试了一些示例。我稍微修改了矩形示例。
我更改了 compute_distance
函数以在第一个参数中按值接受 Point
。
然后我在 compute_distance
.
on_the_stack.origin
之前的 &
这给了我以下错误:
cannot move out of dereference of
&
-pointer
如果我在 on_the_stack.origin
调用之前添加 &
并在 compute_distance
函数中通过引用接受 Point
,它会顺利运行。
第二种方法对我来说很有意义,但为什么我原来的方法会抛出错误?
use std::num::Float;
struct Point {
x : f64,
y : f64
}
struct Size {w: f64, h: f64}
struct Rectangle {origin: Point, size: Size}
#[cfg(not(test))]
fn main() {
let on_the_stack = &Rectangle{origin: Point {x: 1.0, y: 2.0},
size: Size {w: 3.0, h: 4.0}};
let on_the_heap = box Rectangle {origin: Point {x: 5.0, y: 6.0},
size: Size {w: 3.0, h: 4.0}};
println!("Distance: {}", compute_distance(on_the_stack.origin,&on_the_heap.origin));
}
fn compute_distance ( p1:Point,p2:&Point) -> f64 {
let x_d = p1.x - p2.x;
let y_d = p1.y - p2.y;
Float::sqrt(x_d * x_d + y_d * y_d)
}
如您所说,您更改后的 compute_distance
需要 value 作为第一个参数。这意味着该函数将取得参数的所有权。
但是,您正试图传递结构的一小部分(origin
嵌入在 Rectangle
中)。为此,Rust 必须将 Rectangle
的 部分 的所有权赋予该方法,但 Rectangle
究竟会处于什么状态?一个非常破损的,所以 Rust 会阻止你这样做。耶,你没有搬起石头砸自己的脚!
"But wait",你说,"it's totally cool if the function gets a copy of origin
"。作为人类,您可以识别并告诉编译器它是 "totally cool":
#[deriving(Copy)]
struct Point { /* ... */ }
现在 Rust 知道,如果愿意,可以安全地逐位复制 Point
。万岁!
"But wait",你说,"what if it's not cool to make a bit-for-bit copy? My structure needs more love than being treated like a bag of bits!"。同样,作为一个聪明的人,你可以表达:
#[deriving(Clone)]
struct Point { /* ... */ }
// later...
on_the_stack.origin.clone()
现在您可以进行显式调用 (clone()
) 以获取选项的语义副本。因为这可能是一项昂贵的操作,所以编译器不会为您完成。
关于 deriving
在我写这个答案时,deriving
正在过渡到 derive
。根据您的代码需要进行调整。