阅读rust 教程托管和拥有的指针可以按原样传递给需要借用指针的函数,并在编译时转换为借用指针。
为什么堆栈变量不能以相同的方式传递?什么语法或功能需要显式&
运算符传递那个而不是编译器自动转换它?
struct Point {x: float, y: float}
let on_the_stack : Point = Point {x: 3.0, y: 4.0};
let managed_box : @Point = @Point {x: 5.0, y: 1.0};
let owned_box : ~Point = ~Point {x: 7.0, y: 9.0};
fn compute_distance(p1: &Point, p2: &Point) -> float {
let x_d = p1.x - p2.x;
let y_d = p1.y - p2.y;
sqrt(x_d * x_d + y_d * y_d)
}
compute_distance(&on_the_stack, managed_box);
compute_distance(managed_box, owned_box);
更令人困惑的是 ycombinator 上 kibwen 的引述(我找不到原始引述,但这是引述的引述)
我们仍然有 & 和 &mut,但它们不是指针,它们是引用(在我们的文档中称它们为“借用指针”是我们自己的错)
如果compute_distance
正在获取引用并且编译器自动将指针转换为引用,为什么它不能对值做同样的事情?
编辑:由于 pnkfelix 似乎知道他在说什么,我将在此处复制一些对话以便于阅读。
pnkfelix
Rust 的设计者决定在这方面不走 C++ 的道路。这一决定的一个副作用是,当阅读代码的人查看 Rust 中的 f(x, y) 之类的调用时,无需花时间思考“等等,f 如何接受它的参数;如果它改变了 y,将我看到这反映在 f 返回之后?那 x 呢?等等
合资企业
我可能会对引用的性质感到困惑。
@var
并且~var
在 rust 中是指针(尽管它们的行为更像引用) - C++ 引用只是底层的指针吗?无论如何,在代码可读性方面,我可以将相同的逻辑应用于 C。
变量是值或指针(您只需像在 rust 中那样传递变量:)
f(var)
或在函数调用中引用(就像您在 rust 中所做的那样:)f(&var)
- 我原以为 rust 编译器会识别函数签名并处理这是自动的。我看不到 C 或 C++ 的改进
pnkfelix
一个后续:我写的这一行:“等等,f 如何接受它的参数;如果它改变了 y,我会在 f 返回后看到它的反映吗?x 呢?” 有点滑稽,因为即使像 f(&x, y) 这样的调用也无法修改 x;它必须是 f(&mut x, y)。(并且 x 本身的声明必须是 let mut x = ...,等等。 – pnkfelix 1 小时前
第二个后续:为什么在 Rust 中显式 &x 可能比在 C/C++ 中更重要(而不是让 f(x,y) 隐式地进行借用 &x),是因为借用检查器强制借用遵循某些规则,并且会拒绝编译不符合的代码。当您从借用检查器收到错误时,如果编译器在源代码中指向 &x 或 &mut x 形式的表达式,而不是指向函数调用并说“有一个隐式在这里借。” (当然,这是主观意见。) – pnkfelix 1 小时前
我看到你的回复中有一个后续说明,但我不明白你关于将“相同的逻辑应用于 C”的观点。如果您的意思是 C 而不是 C++,那么在调用需要指针的函数时,您通常必须显式地获取内存地址。如果一个函数需要一个
int**
,那么有人需要做&E
whereE
is an l-value typeint*
。在我看来,这类似于 Rust。(我从 C 中临时记得的主要例外是函数指针;你不需要做&f
一个指向 . 的函数指针f
。) – pnkfelix 1 小时前
合资企业
在我看来,这类似于 Rust。- 正是我的观点 - 从可读性的角度来看,与普通 C 相比没有太大的改进。因为借用检查器强制借用遵循某些规则......而是指向函数调用并说“这里有一个隐式借用。 " Bingo - 这是我一直在寻找的根本原因之一。如果您发现手动转换的任何其他原因,请随时添加到您的答案中!