【问题标题】:Not understanding how to access the elements of a vector in Rust [duplicate]不了解如何在 Rust [重复] 中访问向量的元素
【发布时间】:2019-05-10 05:31:07
【问题描述】:

这是我第一次接触 Rust,我正在阅读当前版本的 Rust Book 中关于向量的章节。我以前确实有其他语言的经验(主要是功能性语言,其中隐藏了以下问题)。

运行以下代码 sn-p(来自书中)返回 3

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

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

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

最后,让我们重写上面的代码 sn-ps 彻底消除引用:

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

以上所有内容是否都是在前一章中只提到过一次的自动取消引用的表现? (如果是这样,那么这本书应该重写,因为它比澄清更令人困惑。)

【问题讨论】:

标签: pointers vector reference rust


【解决方案1】:

免责声明:我也在学习 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,即复制语义应用于=,而不是默认的移动语义)。

【讨论】:

    猜你喜欢
    • 2021-12-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-05
    • 1970-01-01
    • 2012-08-08
    • 1970-01-01
    • 2023-01-09
    相关资源
    最近更新 更多