阅读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);
增加了混淆的是来自kibwen在ycombinator上的一句话(我找不到原始引用,但这是引用的引用)
我们仍然有&和&mut,但它们不是指针,它们是引用(我们在文档中称它们为“借用指针”是我们自己的错)
如果compute_distance
正在获取引用,并且编译器会自动将指针转换为引用,为什么不能对值执行相同的操作?
编辑:由于pnkfelix似乎知道他在谈论什么,因此我将在此复制一些对话以便更容易阅读。
pnkfelix
Rust的设计者决定在这方面不遵循C++的路线。 这种决定的一个副作用是,当某人在Rust中看到类似f(x,y)的调用时,他不需要浪费时间想“等等,f如何获取其参数;如果它改变了y,我是否会在f返回之后看到它?x呢?”等等。
J V
我可能对引用的性质感到困惑。 Rust中的
@var
和~var
是指针(虽然它们的行为更像引用),- 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,其中E是类型为int *的l-value。对我来说,这似乎类似于Rust。 (我从C中记得的主要例外是函数指针;您不需要做&f来使函数指针指向f。)-pnkfelix 1小时前
这对我来说似乎与Rust类似。-恰好是我的观点-从可读性的角度来看,与普通的C相比没有太大的改进。因为借用检查器强制执行借用遵循某些规则...而不是指向函数调用并说“这里有一个隐式借用”。" Bingo-这是我寻找的潜在原因之一。如果您发现其他手动转换的原因,请随时添加到您的答案中!
@var
和~var
是指针(虽然它们的行为更像是引用)- C++ 引用在底层是否只是指针呢?无论如何,我可以将相同的逻辑应用于 C 以提高代码可读性。变量要么是值或指针(就像在 Rust 中简单地传递变量一样:f(var)
),要么在函数调用中被引用(就像在 Rust 中所做的那样:f(&var)
)- 我本以为 Rust 编译器会识别函数签名并自动处理这个问题。我没有看到比 C 或 C++ 更好的改进。 - J Vf(&x, y)
这样的调用也无法修改x
;它必须是f(&mut x, y)
。(并且x
本身的声明也必须是let mut x = ...
,等等。 - pnkfelix&x
比在C/C++中更重要的原因(而不是让f(x,y)
隐式地进行借用&x
),是因为借用检查器强制执行某些规则,并且会拒绝编译不符合规范的代码。当您从借用检查器获得错误时,如果编译器指向源代码中的&x
或&mut x
形式的表达式,而不是指向函数调用并说“这里有一个隐式借用”,那么这将是更好的用户体验。(当然,这是主观意见。) - pnkfelixint **
,那么某人需要做&E
,其中E
是类型为int *
的l-value。对我来说,这似乎类似于Rust。(我从C中记得的主要例外是函数指针; 您不需要执行&f
来使函数指针指向f
)。 - pnkfelix