何时取消引用
When to dereference or not
我正在浏览“Rust Book”网站,以便为即将到来的工作面试学习语言。在矢量一章中,有两个代码示例:
fn main() {
let v = vec![100, 32, 57];
for i in &v {
println!("{}", i);
}
}
和:
fn main() {
let mut v = vec![100, 32, 57];
for i in &mut v {
*i += 50;
}
}
现在我想知道,为什么对于第一个样本,当我们将对向量元素 i 的引用传递给:
println!("{}", i);
但是在我们向向量的每个元素添加 50 的示例中,我们必须在添加到 50 之前使用 * 取消引用该元素?
我们为什么不t/can做以下事情:
fn main() {
let v = vec![100, 32, 57];
for i in &v {
println!("{}", *i); // why don't we have to dereference before we pass to println!?
}
}
或:
fn main() {
let mut v = vec![100, 32, 57];
for i in &mut v {
i += 50; // why can't we just add directly to the reference like this?
}
}
我一定是误解了我读到的内容,但我认为 Rust 能够辨别您何时需要自动取消引用或不需要。我想我不明白为什么我们需要在两个示例中取消引用(或不取消引用)。我提供的两个示例用我想知道的特定代码位进行了注释。
我认为最简单的方法是将第二个示例视为“正常”示例。
fn main() {
let mut v = vec![100, 32, 57];
for i in &mut v {
*i += 50;
}
}
i
是一个 &mut i32
(只有 i32
因为没有什么可以从中推断任何其他整数类型),所以要分配给它你需要取消引用一个 mut i32
.
println!
示例是一个“魔术”示例。 println!
将格式化类型,无论它们是按值还是按引用传递。这非常方便,您不希望它(例如)克隆您要打印的每个字符串,然后在应用程序中稍后使用。
编辑:
为了完整起见,这种“魔法”根本不是真正的魔法,而是对语言特性的巧妙运用。 println!
(与其他所有进行格式化的标准宏一样,如 panic!
和 format!
)使用 formatting machinery from the standard library. This can work with any type that implements the Display
trait (or the Debug
trait if you use {:?}
). And Display
has a blanket impl 来实现 Display
(Debug
也这样做):
impl<'_, T> Display for &'_ T where
T: Display + ?Sized,
{ /* ... */ }
所以任何你可以用值格式化的东西,你也可以用引用格式化。
我正在浏览“Rust Book”网站,以便为即将到来的工作面试学习语言。在矢量一章中,有两个代码示例:
fn main() {
let v = vec![100, 32, 57];
for i in &v {
println!("{}", i);
}
}
和:
fn main() {
let mut v = vec![100, 32, 57];
for i in &mut v {
*i += 50;
}
}
现在我想知道,为什么对于第一个样本,当我们将对向量元素 i 的引用传递给:
println!("{}", i);
但是在我们向向量的每个元素添加 50 的示例中,我们必须在添加到 50 之前使用 * 取消引用该元素?
我们为什么不t/can做以下事情:
fn main() {
let v = vec![100, 32, 57];
for i in &v {
println!("{}", *i); // why don't we have to dereference before we pass to println!?
}
}
或:
fn main() {
let mut v = vec![100, 32, 57];
for i in &mut v {
i += 50; // why can't we just add directly to the reference like this?
}
}
我一定是误解了我读到的内容,但我认为 Rust 能够辨别您何时需要自动取消引用或不需要。我想我不明白为什么我们需要在两个示例中取消引用(或不取消引用)。我提供的两个示例用我想知道的特定代码位进行了注释。
我认为最简单的方法是将第二个示例视为“正常”示例。
fn main() {
let mut v = vec![100, 32, 57];
for i in &mut v {
*i += 50;
}
}
i
是一个 &mut i32
(只有 i32
因为没有什么可以从中推断任何其他整数类型),所以要分配给它你需要取消引用一个 mut i32
.
println!
示例是一个“魔术”示例。 println!
将格式化类型,无论它们是按值还是按引用传递。这非常方便,您不希望它(例如)克隆您要打印的每个字符串,然后在应用程序中稍后使用。
编辑:
为了完整起见,这种“魔法”根本不是真正的魔法,而是对语言特性的巧妙运用。 println!
(与其他所有进行格式化的标准宏一样,如 panic!
和 format!
)使用 formatting machinery from the standard library. This can work with any type that implements the Display
trait (or the Debug
trait if you use {:?}
). And Display
has a blanket impl 来实现 Display
(Debug
也这样做):
impl<'_, T> Display for &'_ T where
T: Display + ?Sized,
{ /* ... */ }
所以任何你可以用值格式化的东西,你也可以用引用格式化。