我正在学习 Rust,并试图解决代码挑战的出现(2015 年第 9 天)。
我创建了一种情况,最终得到一个具有该类型的变量Vec<&&str>(注意双“&”,这不是拼写错误)。我现在想知道这种类型是否与Vec<&str>. 我不知道对某事物的引用是否有意义。我知道我可以通过使用Stringforfrom和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 {
...
}
Run Code Online (Sandbox Code Playgroud)
我现在想知道这种类型是否与
Vec<&str>.
是的, aVec<&&str>是一种不同于Vec<&str>- 你不能在需要Vec<&&str>a 的地方传递 a Vec<&str>,反之亦然。Vec<&str>存储字符串切片引用,您可以将其视为指向某些字符串内的数据的指针。Vec<&&str>存储对此类字符串切片引用的引用,即指向数据指针的指针。对于后者,访问字符串数据需要额外的间接寻址。
然而,Rust 的自动取消引用使得使用a变得可能,Vec<&&str>就像使用 a 一样Vec<&str>- 例如,v[0].len()在任何一个上都可以很好地工作,v[some_idx].chars()将用任何一个迭代字符,等等。唯一的区别是Vec<&&str>更间接地存储数据,因此每次访问都需要更多的工作,这可能会导致代码效率稍低。
请注意,您始终可以将 a 转换Vec<&&str>为Vec<&str>- 但由于这样做需要分配一个新向量,因此如果您决定不需要Vec<&&str>,最好首先不要创建它。
由于 a&str是,因此您可以通过在迭代时添加 a 来Copy避免创建,即更改为。如果你不需要留下来,你也可以使用,它会在迭代完成后立即给出,以及自由向量。Vec<&&str>.copied()verticesvertices.iter()vertices.iter().copied()verticesvertices.into_iter()&strvertices
StackOverflow 之前已经介绍了出现额外引用的原因以及避免它的方法。
这本身并没有什么错误,Vec<&&str>需要人们避免它。Vec<&&str>在大多数代码中,您永远不会注意到和之间的效率差异Vec<&str>。话虽如此,除了微基准测试的性能之外,还有一些理由避免它。额外的间接寻址Vec<&&str>需要它所创建的确切&strs(而不仅仅是拥有数据的字符串)才能保留并比新集合的寿命更长。这与您的情况无关,但如果您想将排列返回给拥有字符串的调用者,则会变得明显。此外,更简单的类型也有价值,它不会在每个转换上累积引用。想象一下需要将其Vec<&&str>进一步转换为一个新的向量 - 你不会想处理Vec<&&&str>为每个新转换处理 ,等等。
就性能而言,间接性越少通常越好,因为它避免了额外的内存访问并增加了数据局部性。然而,还应该注意的是,Vec<&str>每个元素 a 占用 16 个字节(在 64 位架构上),因为切片引用由“胖指针”(即指针/长度对)表示。另一方面,A Vec<&&str>(以及等)每个元素仅占用 8 个字节,因为对胖引用的引用由常规“瘦”指针表示。Vec<&&&str>因此,如果你的向量测量了数百万个元素,aVec<&&str>可能比仅仅因为它占用更少的内存更有效Vec<&str>。一如既往,如果有疑问,请进行测量。