【问题标题】:Reference to a vector still prints as a vector?对向量的引用仍然打印为向量?
【发布时间】:2015-04-17 16:58:42
【问题描述】:

愚蠢的 n00b 试图学习一些关于 Rust 的知识。这是我的程序:

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

产生了输出:

[1, 2, 3]
[1, 2, 3]

& 的意义何在?我有一半希望它打印内存地址。

我最初是在intro 中被这个抛出的,看起来他们正在循环通过一个引用。我的猜测是 Rust 做了一些魔术并检测到它是一个向量的内存地址?

【问题讨论】:

    标签: pointers rust


    【解决方案1】:

    & 的意义何在?

    如您所料,& 采用对象的引用。但是,有一个 Debug implementation for references to Debug types 只是打印出引用的对象。这样做是因为 Rust 倾向于值相等而不是引用相等:

    impl<'a, T: ?Sized + $tr> $tr for &'a T {
        fn fmt(&self, f: &mut Formatter) -> Result { $tr::fmt(&**self, f) }
    }
    

    如果要打印内存地址,可以使用{:p}

    let v = vec![1,2,3];
    println!("{:p}", &v);
    

    看起来他们正在循环引用一个参考

    for i in foo 语法糖在 foo 上调用 into_iterator,并且有一个 implementation of IntoIterator for &amp;Vec 返回一个迭代器,该迭代器对迭代器中的项进行引用:

    fn into_iter(self) -> slice::Iter<'a, T> {
        self.iter()
    }
    

    【讨论】:

    • 谢谢。我阅读了关于迭代器的部分,发现for i in &amp;v 给了我 i 作为对 v 的每个元素的引用。for 循环正在发挥神奇的作用,我想知道我想要对可迭代的每个元素的引用——而不是尝试遍历指针。对吗?
    • @speg 我添加了一部分。基本上,for i in foo 使用IntoIterator,并且有一个用于委托给Vec::iter&amp;Vec&lt;T&gt; 特征的实现。 Vec::iter 返回一个迭代器,它产生对向量中每个项目的引用。
    【解决方案2】:

    神奇的是格式化程序而不是编译器中的 AFAIK。例如:

    fn take_val<T>(a:Vec<T> ) {}
    fn take_ref<T>(b:&Vec<T>) {}
    
    fn main() {
        let v = vec![1, 2, 3];
        take_val(&v);
        take_ref(&v);
    
    }
    

    失败并出现以下错误:

    <anon>:6:14: 6:16 error: mismatched types:
     expected `collections::vec::Vec<_>`,
        found `&collections::vec::Vec<_>`
    (expected struct `collections::vec::Vec`,
        found &-ptr) [E0308]
    <anon>:6     take_val(&v);
    

    这表明这是由于格式化程序不想显示引用和值之间的差异。如果我没记错的话,在旧版本的 Rust 中,&amp;v 会显示为 &amp;[1, 2, 3]

    &amp; 在 Rust 中具有特殊含义。它不仅仅是一个参考,它是一个注释,该值被借用给一个或多个函数/方法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-04-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-31
      • 2017-10-31
      相关资源
      最近更新 更多