我正在学习 Rust,并试图解决代码挑战的出现(2015 年第 9 天)。
我创建了一种情况,最终得到一个类型为 Vec<&&str>
的变量。 (注意双“&”,这不是拼写错误)。我现在想知道这种类型是否与 Vec<&str>
不同。我不知道对某事物的引用是否有意义。我知道我可以通过使用 String
来避免这种情况对于from
和to
变量。我问是否 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> 以及如何避免吗?
自 &str
是 Copy
,您可以避免创建 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/