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);
}