在Rust中创建向量的向量 [英] Creating a Vector of Vectors in Rust
问题描述
此代码无法编译:
fn main() {
let m1 = vec![1, 2, 3];
let m2 = vec![&m1, &m1, &m1];
let m3 = vec![vec![1, 2, 3], vec![4, 5, 6], vec![7, 8, 9]];
for i in &m2 {
for j in i {
println!("{}", j);
}
}
for i in &m3 {
for j in i {
println!("{}", j);
}
}
}
error[E0277]: the trait bound `&&std::vec::Vec<{integer}>: std::iter::Iterator` is not satisfied
--> src/main.rs:8:18
|
8 | for j in i {
| ^ `&&std::vec::Vec<{integer}>` is not an iterator; maybe try calling `.iter()` or a similar method
|
= help: the trait `std::iter::Iterator` is not implemented for `&&std::vec::Vec<{integer}>`
= note: required by `std::iter::IntoIterator::into_iter`
-
m2
与m3
有何不同,以致m3
不会引起问题,但m2
会阻止编译?
How is
m2
different thanm3
such thatm3
causes no issues, butm2
prevents compilation?
是否有一种更简单的方法来创建向量...的向量到所需的深度?我的工作方式(m3
)似乎很笨拙.
Is there an easier way to create a vector of vector of... to any desired depth? The way I have it working (m3
) seems so clunky.
推荐答案
m2
与m3
有何不同...
How is
m2
different thanm3
...
逐步检查类型. m1
的类型为Vec<isize>
(也可以是任何其他整数类型,但我现在认为它是isize
).为什么?因为vec![]
宏中的元素是isize
类型.现在,您正在创建m2
:
Check the types step by step. m1
is of type Vec<isize>
(it could be any other integer type as well, but I assume it's isize
for now). Why? Because the elements in the vec![]
macro are of type isize
. Now you are creating m2
:
let m2 = vec![&m1, &m1, &m1];
此宏中元素的类型是什么?好了,我们已经说过m1
具有类型Vec<isize>
,所以&m1
具有类型&Vec<isize>
.因此,结果m2
的类型为Vec<&Vec<isize>>
(一个充满对其他向量的引用的向量).
What is the type of the elements in this macro? Well we already said m1
has the type Vec<isize>
, so &m1
has the type &Vec<isize>
. So the resulting type of m2
is Vec<&Vec<isize>>
(a vector full of references to other vectors).
但是,m3
的类型为Vec<Vec<isize>>
,因为(外部)vec![]
宏中的元素的类型为Vec<isize>
(无引用!).
However, m3
is of type Vec<Vec<isize>>
, since the elements in the (outer) vec![]
macro are of type Vec<isize>
(no reference!).
提示:轻松检查任何变量的类型(例如foo
),输入:
Hint: to easily check the type of any variable (such as foo
), type:
let _: () = foo;
这将导致编译器错误,告诉您foo
的类型.
This will result in a compiler error that tells you the type of foo
.
...使得
m3
不会出现问题,但是m2
会阻止编译?
... such that
m3
causes no issues, butm2
prevents compilation?
现在我们知道了m2
和m3
的类型,让我们看一下循环. for
通过接受实现 IntoIterator
.您正在传递类型为&Vec<&Vec<isize>>
的&m2
(请注意两个引用). 我们可以看到,IntoIterator
确实针对对向量的引用:
Now that we know the types of m2
and m3
, lets look at the loops. for
loops work by accepting something that implements IntoIterator
. You are passing &m2
, which is of type &Vec<&Vec<isize>>
(note the two references). We can see, that IntoIterator
is indeed implemented for a reference to a vector:
impl<T> IntoIterator for &Vec<T> {
type Item = &T
// ...
}
这意味着您将获得一个迭代器,该迭代器吐出对内部类型T
(type Item = &T
)的引用.我们的内部类型m2
是&Vec<isize>
,因此我们将获得类型&&Vec<isize>
的项(两个引用!).您的变量i
具有此确切类型.
This means that you get an iterator that spits out references to the inner type T
(type Item = &T
). Our inner type of m2
is &Vec<isize>
, so we will get items of type &&Vec<isize>
(two references!). Your variable i
has this exact type.
然后您要使用此内循环再次进行迭代:
Then you want to iterate again with this inner loop:
for j in i { ... }
但是i
具有这种双重引用类型,并且该类型没有IntoIterator
的实现.要对其进行迭代,您必须像这样取消对它的引用:
But i
has this double-reference type and there isn't an implementation of IntoIterator
for that type. To iterate it, you have to either dereference it like:
for j in *i { ... }
甚至更好:将i
设为&Vec<isize>
类型(一个参考!),方法是在外循环中使用模式匹配将其剥离:
Or even better: make i
be of the type &Vec<isize>
(one reference!) by stripping it away with pattern matching in the outer loop:
for &i in &m2 { ... }
您的m3
循环执行相同的操作,但是由于m3
是另一种类型(较少引用),因此它可以工作(希望您能看到原因).
Your m3
loop does the same, but since m3
is of another type (with one reference less), it works (I hope you can see why).
有没有一种简便的方法可以创建一个向量...到任意所需深度的向量
Is there an easier way to create a vector of vector of... to any desired depth
即使m2
工作正常,它也不会具有与m3
相同的值.要使m2
的类型为Vec<Vec<isize>>
(如m3
),应使用clone
m1
而不是对其进行引用.
Even if m2
worked, it wouldn't hold the same values as m3
. To make m2
of the type Vec<Vec<isize>>
(like m3
), you should clone
m1
instead of taking a reference to it.
let m2 = vec![m1.clone(), m1.clone(), m1.clone()];
使用宏的vec![_; _]
形式,我们可以做得更好:
We can do even better by using the vec![_; _]
form of the macro:
let m2 = vec![m1; 3]; // three times the value of `m1`
最后一点,您应该考虑使用嵌套的Vec
而不是 .嵌套会产生开销,因为这些值分布在整个内存中,而不是放在一个位置.
As a last note, you should consider not using nested Vec
s. The nesting creates overhead because the values are spread over the whole memory instead of being in one place.
这篇关于在Rust中创建向量的向量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!