Vector 当在向量上进行迭代时,当推到向量时,锈迹会保护我不受迭代器失效的影响吗?
锈能保护我免受迭代器失效吗?或者我只是幸运地使用了Vector 当在向量上进行迭代时,当推到向量时,锈迹会保护我不受迭代器失效的影响吗?,vector,iterator,rust,invalidation,Vector,Iterator,Rust,Invalidation,锈能保护我免受迭代器失效吗?或者我只是幸运地使用了realloc?为和'Vec返回的迭代器提供了什么保证 在Rust中,大多数方法都使用&self——对self的引用。在大多数情况下,像some_string.len()这样的调用在内部“扩展”为如下内容: let a: String = "abc".to_string(); let a_len: usize = String::len(&a); // This is identical to calling `a.len()`. 但是
realloc
?为和'Vec
返回的迭代器提供了什么保证
在Rust中,大多数方法都使用
&self
——对self的引用。在大多数情况下,像some_string.len()
这样的调用在内部“扩展”为如下内容:
let a: String = "abc".to_string();
let a_len: usize = String::len(&a); // This is identical to calling `a.len()`.
但是,请考虑对对象的引用:<代码> AyReF,这是引用<代码> A<代码>的<代码>字符串>代码>。Rust非常聪明,可以决定是否需要添加或删除引用,就像我们上面看到的(
a
变成&a
);在这种情况下,a_ref.len()
扩展为:
let a: String = "abc".to_string();
let a_ref: &String = &a;
let a_len: usize = String::len(a_ref); // This is identical to calling `a_ref.len();`. Since `a_ref` is a reference already, it doesn't need to be altered.
请注意,这基本上与原始示例相同,只是我们使用的是对a
的显式设置引用,而不是直接使用a
这意味着v.clone()
扩展到Vec::clone(&v)
,同样地,v\u ref.clone()
扩展到Vec::clone(v\u ref)
,并且由于v\u ref
是&v
(或者具体地说,&mut v
),我们可以将其简化为Vec::clone(&v)
。换句话说,这些调用相当于对对象的基本引用(&
)调用clone()
)不会克隆引用,而是克隆引用的对象
换句话说,Tamas Hedgeus的评论是正确的:您正在迭代一个新的向量,其中包含的元素是v
中元素的克隆。在for
循环中迭代的项不是&Vec
,而是与v
分开的Vec
,因此迭代器无效不是问题
至于你关于Rust提供的担保的问题,你会发现Rust的借阅检查器处理得相当好,没有任何附加条件
但是,如果要这样做,您将收到一条错误消息,使用移动值:'*v_ref'
,因为当您对v_ref
进行迭代时,v_ref
被视为“移动”到for
循环中,并且不能用于函数的其余部分;为了避免这种情况,iter函数创建了一个迭代器对象,该对象只借用向量,允许您在循环结束(迭代器被删除)后重用向量。如果您尝试不使用v_ref
抽象,则错误读取不能将“v”借用为可变的,因为它也借用为不可变的
v
在v.iter()
生成的迭代器中不可变地借用(其类型签名为fn iter(&self)->iter
-注意,它对向量进行借用),并且在删除迭代器(在for
循环的末尾)之前,不允许您由于Rust的借用检查器而对向量进行变异. 但是,由于可以对单个对象有多个不可变引用,因此仍然可以在for循环中读取向量,而不是写入向量
如果在迭代向量时需要对向量的元素进行变异,可以使用,它一次返回对一个元素的可变引用,并且只允许更改该元素。您仍然无法使用
iter_mut
对迭代向量本身进行变异,因为Rust确保一次只有一个对象的可变引用,以及确保在同一范围内没有对某个对象的可变引用与对该对象的不可变引用。我不是生锈专家,但看起来您迭代的是克隆,而不是原始的vec.TL;答案博士:是的,但这只有在你实际推动你正在迭代的向量时才起作用。顺便说一句:锈菌的“扩展”机制实际上是处理特质碰撞所必需的。如果trait Foo
和trait Bar
都实现了fn-qux(&self)
,并且您有一个类型为FooBar
的对象,该对象同时实现了Foo
和Bar
,您可以通过编写:qux(&FooBar)
(或根据需要将其作为Bar
)来选择要使用的实现。对对象的基本引用(&
)调用clone()
)不会克隆该引用,这不是普遍正确的。当引用的类型未实现clone
@Shepmaster时,它会克隆引用-我不知道这一点。我认为,尝试对未定义clone
的引用调用clone
会导致错误,或者与克隆引用对象相比,克隆引用有一种特殊的方法,以避免混淆。直到。
let a: String = "abc".to_string();
let a_ref: &String = &a;
let a_len: usize = String::len(a_ref); // This is identical to calling `a_ref.len();`. Since `a_ref` is a reference already, it doesn't need to be altered.