首页 文章

不了解如何访问Rust中的向量元素[重复]

提问于
浏览
0

这个问题在这里已有答案:

这是我第一次遇到Rust,我正在阅读当前版本的Rust Book中关于向量的章节 . 我之前有过使用其他语言的经验(主要是功能性的,隐藏了以下问题) .

运行以下代码片段(从书中)返回 3

fn main() {
  let v = vec![1, 2, 3, 4, 5];
  let third: &i32 = &v[2];
  println!("{}", third);
}
  • 我不明白的第一件事是为什么没有引用 println! 宏内的 third . 我希望上面的代码打印 v 的第3个元素的内存地址(如C和C中所示),而不是其内容 .

现在考虑代码(这次在 println! 内注意引用):

fn main() {
  let v = vec![1, 2, 3, 4, 5];
  let third: &i32 = &v[2];
  println!("{}", *third);
}
  • 为什么上面的代码产生与上面的代码完全相同的输出,好像 * 没有区别?

最后,让我们重写上面的代码片段,完全消除引用:

fn main() {
  let v = vec![1, 2, 3, 4, 5];
  let third: i32 = v[2];
  println!("{}", third);
}
  • 为什么最后一个版本产生与前两个版本相同的输出? v[2] 究竟有什么类型:是 &i32 还是 i32

上述所有内容都是自动解除引用的一种表现形式,只是在前一章中曾经提到过吗? (如果是这样,那么这本书应该被重写,因为它比澄清更令人困惑 . )

1 回答

  • 0

    免责声明:我也在学习Rust,所以请带上一粒盐 .

    要了解发生了什么,使用cargo-expand可能会更容易 .

    对于代码

    fn main() {
      let v = vec![1, 2, 3, 4, 5];
      let third: &i32 = &v[2];
      println!("{}", third);
    }
    

    我们得到了(我删除了不相关的代码)

    fn main() {
        ...
        let third: ...
        {
            ::io::_print(::std::fmt::Arguments::new_v1_formatted(                            
                ...
                &match (&third,) {                                                           
                    (arg0,) => [::std::fmt::ArgumentV1::new(arg0, ::std::fmt::Display::fmt)],
                },
                ...
            ));
        };
    }
    

    对于第一个/最后一个案例,和

    fn main() {
        ...
        let third: ...
        {
            ::io::_print(::std::fmt::Arguments::new_v1_formatted(                            
                ...
                &match (&*third,) {                                                           
                    (arg0,) => [::std::fmt::ArgumentV1::new(arg0, ::std::fmt::Display::fmt)],
                },
                ...
            ));
        };
    }
    

    对于第二种情况 .

    粗略地,这意味着,对于 {} 格式化程序,将分别调用函数 fmt (特征 Display )以引用 third*third .

    让我们应用这个逻辑

    • 第二种情况: third: &i32 然后 *third: i32 ,这是impl Display for i32适用的地方 .

    • 第一种情况: third: &i32 ,这也是因为impl<', T> Display for &' T(其中 Ti32

    • 最后一种情况: third: i32 :与第一种情况相同 . 此外, v[2] (类型为 i32 )的工作原理是因为impl Index for Vec(注意: let third = v[2] 有效,因为impl Copy for i32,即复制语义适用于 = 而不是默认的移动语义) .

相关问题