Vec中的Rust元组:使用val0方法时发生编译错误
在以下情况下,我会遇到令人困惑的编译错误:Vec中的Rust元组:使用val0方法时发生编译错误,rust,Rust,在以下情况下,我会遇到令人困惑的编译错误: 我创建了一个包含元组的向量,元组本身包含字符串 方法“val0”(或“val1”,等等)被调用于该向量的任何项 下面是一个代码示例: fn main() { let mut v = Vec::<(int,String)>::new(); v.push((3, String::new())); let u = v[0].val0(); } 我认为我对所有权、借阅、引用和使用寿命有了合理的理解,但我仍然没有发现这
- 我创建了一个包含元组的向量,元组本身包含字符串
- 方法“val0”(或“val1”,等等)被调用于该向量的任何项
fn main()
{
let mut v = Vec::<(int,String)>::new();
v.push((3, String::new()));
let u = v[0].val0();
}
我认为我对所有权、借阅、引用和使用寿命有了合理的理解,但我仍然没有发现这个错误。为什么会这样
更新:
谢谢你的回答,弗拉基米尔和莱文斯
Vladimir,我将按照建议使用元组索引语法,但我最感兴趣的是“为什么”。为什么这么简单的东西不能工作
正如Levans所说,val0的定义是:
fn val0(self) -> A
我设法进一步简化了我的示例:
fn main()
{
let t : (int, String) = (3, String::new());
let u = t.val0();
let v = t.val1();
}
这会导致以下错误:
main.rs:8:13: 8:14 error: use of moved value: `t`
main.rs:8 let v = t.val1();
main.rs:7:13: 7:14 note: `t` moved here because it has type `(int,collections::string::String)`, which is non-copyable (perhaps you meant to use clone()?)
main.rs:7 let u = t.val0();
这就是我要找的。我缺少的是复杂类型不能通过值复制。因此,它们被移动到调用的函数的范围
请注意,以下操作确实有效,因为(int,int)不是复杂类型:
fn main()
{
let t : (int, int) = (3, 4);
let u = t.val0();
let v = t.val1();
}
我仍然认为在原始示例(使用Vec)的错误消息中包含更多信息将非常有用。val0()的原型是:
fn val0(self) -> A
如您所见,它使用元组来展开第一个值。因此,当您在v[0]
上调用它时,它会有效地尝试将元组移动到val0()
的范围内,这是禁止的,因为元组属于您的Vec
您可能希望使用ref0
,它提供对第一项的引用,而不使用元组:
fn ref0(&'a self) -> &'a A
使用最新的Rust编译器,您不需要
valX()
/refX()
方法,您可以使用元组索引语法。事实上,我很惊讶它们没有被弃用(可能是因为元组索引仍然在功能门后面)。元组索引如下所示:
#![feature(tuple_indexing)]
fn main() {
let mut v = Vec::<(int,String)>::new();
v.push((3, String::new()));
let u = v[0].0; // use 1st (with zero-based indices) field of a tuple
println!("{}", u);
}
#![特征(元组索引)]
fn main(){
让mut v=Vec:::new();
v、 push((3,String::new());
设u=v[0].0;//使用元组的第1个(以零为基的索引)字段
println!(“{}”,u);
}
幸运的是,这个程序可以工作,因为访问元组字段就像访问常规结构中的字段一样——它不需要拥有整个结构的所有权,并且支持部分移动。在这种特殊情况下,第一个字段类型是隐式可复制的,因此您只需访问它,它就会被复制
#![feature(tuple_indexing)]
fn main() {
let mut v = Vec::<(int,String)>::new();
v.push((3, String::new()));
let u = v[0].0; // use 1st (with zero-based indices) field of a tuple
println!("{}", u);
}