Ale*_* M. 5 pointers reference vector rust
这是我第一次接触 Rust,我正在阅读Rust Book当前版本中关于向量的章节。我之前确实有使用其他语言的经验(主要是函数式语言,其中隐藏了以下问题)。
运行以下代码片段(来自本书)返回3:
fn main() {
let v = vec![1, 2, 3, 4, 5];
let third: &i32 = &v[2];
println!("{}", third);
}
Run Code Online (Sandbox Code Playgroud)
third内部println!。我本来希望上面的代码打印v(如在 C 和 C++ 中)的第三个元素的内存地址,而不是它的内容。现在考虑代码(注意这次里面的引用println!):
fn main() {
let v = vec![1, 2, 3, 4, 5];
let third: &i32 = &v[2];
println!("{}", *third);
}
Run Code Online (Sandbox Code Playgroud)
*没有什么区别?最后,让我们重写上面的代码片段,完全消除引用:
fn main() {
let v = vec![1, 2, 3, 4, 5];
let third: i32 = v[2];
println!("{}", third);
}
Run Code Online (Sandbox Code Playgroud)
v[2]确实有:它是 an&i32还是 an i32?以上所有内容是否都是前一章中仅提及一次的自动取消引用的表现?(如果是这样,那么这本书应该重写,因为它比澄清更令人困惑。)
免责声明:我也在学习 Rust,所以请对此持保留态度。
要了解发生的情况,使用cargo-expand可能会更容易。
对于代码
fn main() {
let v = vec![1, 2, 3, 4, 5];
let third: &i32 = &v[2];
println!("{}", third);
}
Run Code Online (Sandbox Code Playgroud)
我们得到(我已经删除了不相关的代码)
fn main() {
...
let third: ...
{
::io::_print(::std::fmt::Arguments::new_v1_formatted(
...
&match (&third,) {
(arg0,) => [::std::fmt::ArgumentV1::new(arg0, ::std::fmt::Display::fmt)],
},
...
));
};
}
Run Code Online (Sandbox Code Playgroud)
对于第一个/最后一个案例,以及
fn main() {
...
let third: ...
{
::io::_print(::std::fmt::Arguments::new_v1_formatted(
...
&match (&*third,) {
(arg0,) => [::std::fmt::ArgumentV1::new(arg0, ::std::fmt::Display::fmt)],
},
...
));
};
}
Run Code Online (Sandbox Code Playgroud)
对于第二种情况。
粗略地说,这意味着,对于格式化程序,将分别调用(特征的){}函数来引用或。fmtDisplaythird*third
让我们应用这个逻辑
第二种情况:third: &i32那么*third: i32,这就是impl Display for i32适用的地方。
第一种情况:third: &i32,这也有效,因为impl<'_, T> Display for &'_ T(其中T是i32)
最后一种情况: third: i32: 与第一种情况相同。此外,v[2](其类型为i32)之所以有效,是因为impl Index for Vec(请注意:let third = v[2]有效是因为impl Copy for i32,即应用复制语义=而不是默认的移动语义)。
| 归档时间: |
|
| 查看次数: |
2015 次 |
| 最近记录: |