rust - Vec<&&str> 与 Vec<&Str> 相同吗?

标签 rust reference

我正在学习 Rust,并试图解决代码挑战的出现(2015 年第 9 天)。

我创建了一种情况,最终得到一个类型为 Vec<&&str> 的变量。 (注意双“&”,这不是拼写错误)。我现在想知道这种类型是否与 Vec<&str> 不同。我不知道对某事物的引用是否有意义。我知道我可以通过使用 String 来避免这种情况对于fromto变量。我问是否 Vec<&&str> == Vec<&str>如果我应该尝试避免 Vec<&&str> .

这是触发此问题的代码:

use itertools::Itertools
use std::collections::{HashSet};

fn main() {
    let contents = fs::read_to_string("input.txt").unwrap();

    let mut vertices: HashSet<&str> = HashSet::new();

    for line in contents.lines() {

        let data: Vec<&str> = line.split(" ").collect();

        let from = data[0];
        let to = data[2];

        vertices.insert(from);
        vertices.insert(to);
    }

    // `Vec<&&str>` originates from here
    let permutations_iter = vertices.iter().permutations(vertices.len());

    for perm in permutations_iter {
        let length_trip = compute_length_of_trip(&perm);
    }
}

fn compute_length_of_trip(trip: &Vec<&&str>) -> u32 {
    ...
}

最佳答案

Vec<&str> 和 Vec<&&str> 类型不同吗?

I'm now wondering if this type is different than Vec<&str>.

是的,一个Vec<&&str>是与 Vec<&str> 不同的类型- 你不能通过Vec<&&str>其中 Vec<&str>是预期的,反之亦然。 Vec<&str>存储字符串切片引用,您可以将其视为指向某些字符串内的数据的指针。 Vec<&&str>存储对此类字符串切片引用的引用,即指向数据指针的指针。对于后者,访问字符串数据需要额外的间接。

但是,Rust 的自动取消引用使得可以使用 Vec<&&str>就像您使用 Vec<&str> 一样- 例如,v[0].len() v[some_idx].chars() 都可以正常工作将使用其中之一迭代字符,依此类推。唯一的区别是Vec<&&str>更间接地存储数据,因此每次访问都需要更多的工作,这可能会导致代码效率稍低。

请注意,您始终可以转换 Vec<&&str>Vec<&str> - 但由于这样做需要分配一个新向量,如果您决定不想要 Vec<&&str> ,最好一开始就不要创建它。

我可以避免 Vec<&&str> 以及如何避免吗?

&strCopy ,您可以避免创建 Vec<&&str>通过添加 .copied()当您迭代 vertices 时,即更改vertices.iter()vertices.iter().copied() 。如果不需要vertices留下来,您还可以使用 vertices.into_iter() ,这将给出 &str ,以及免费 vertices迭代完成后立即向量。

额外引用产生的原因以及避免的方法已covered on StackOverflow之前。

我应该避免 Vec<&&str> 吗?

Vec<&&str> 没有任何本质上的错误。这需要人们避免它。在大多数代码中,您永远不会注意到 Vec<&&str> 之间的效率差异。和Vec<&str> 。话虽如此,除了微基准测试的性能之外,还有一些理由避免它。 Vec<&&str> 中的附加间接寻址需要准确的&str它是根据(而不仅仅是拥有数据的字符串)创建的,以便保留并比新集合的生命周期更长。这与您的情况无关,但如果您想将排列返回给拥有字符串的调用者,则会变得明显。此外,更简单的类型也有值(value),它不会在每个转换上累积引用。想象一下需要改造 Vec<&&str>进一步进入一个新向量 - 你不会想处理 Vec<&&&str> ,等等对于每个新的转换。

关于性能,间接性越少通常越好,因为它可以避免额外的内存访问并增加数据局部性。然而,人们还应该注意到 Vec<&str>每个元素占用 16 个字节(在 64 位架构上),因为切片引用由“胖指针”(即指针/长度对)表示。一个Vec<&&str> (以及 Vec<&&&str> 等)另一方面,每个元素仅占用 8 个字节,因为对胖引用的引用由常规“瘦”指针表示。因此,如果您的向量测量了数百万个元素,则 Vec<&&str>可能比 Vec<&str> 更高效很简单,因为它占用的内存更少。一如既往,如果有疑问,请进行测量。

关于rust - Vec<&&str> 与 Vec<&Str> 相同吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70399256/

相关文章:

generics - trait 不能做成一个对象

c - 为什么使用libc阻止正常链接我的程序?

rust - 了解 &* 以访问 Rust Arc

linux - 使用rustbook工具时,如何解决librustdoc.so丢失的问题?

perl - 将数组中的值取消引用到一行中声明的变量

php - PHP 中的 $$ 数组变量

c++ - 通过引用传递创建的对象 'on the fly'

rust - 在结构中的函数指针类型中指定生命周期

java - 比较字符串引用

c# - 重新分配类索引的数组(引用类型)