繁体   English   中英

索引Box错误的Vec

[英]Indexing a Vec of Box Error

我正在玩Vec结构并遇到一些我无法理解的有趣错误和行为。 请考虑以下代码

fn main() {
    let v = vec![box 1i];
    let f = v[0];
}

在Rust围栏中进行评估时,代码会产生以下错误:

<anon>:3:13: 3:17 error: cannot move out of dereference (dereference is implicit, due to indexing)
<anon>:3     let f = v[0];
                     ^~~~
<anon>:3:9: 3:10 note: attempting to move value to here (to prevent the move, use `ref f` or `ref mut f` to capture value by reference)
<anon>:3     let f = v[0];
                 ^
error: aborting due to previous error
playpen: application terminated with error code 101
Program ended.

我对Vecindex方法的理解是它返回对Vec值的Vec ,所以我不明白是什么动作或隐式解引用正在发生。

此外,当我f变量更改为下划线时 ,如下所示,不会产生错误!

fn main() {
    let v = vec![box 1i];
    let _ = v[0];
}

我希望有人可以解释我遇到的错误,以及为什么他们在将f切换为_时会消失。

不知道哪个语法糖v[0]实现了,但它试图移动值而不是获取引用。

但是如果你调用.index() ,它会工作并为你提供一个与向量相同生命周期的引用:

fn main() {
    let v = vec![box 1i];
    let f = v.index(&0);
    println!("{}", f);
}

第二个示例有效,因为当值被丢弃时,它不会尝试移动它。

编辑:

v[0]*v.index(&0)*v.index(&0) (来自: https//github.com/rust-lang/rust/blob/fb72c4767fa423649feeb197b50385c1fa0a6fd5/src/librustc/middle/trans/expr.rs#L467 ) 。

fn main() { 
    let a = vec!(1i);
    let b = a[0] == *a.index(&0);
    println!("{}" , b);
}

true

在你的代码中, let f = v[0]; 按值分配f(如错误消息中所述,它隐式取消引用):编译器尝试将v[0]复制或移动到f v[0]是一个box ,它无法复制,因此它应该像这种情况一样移动:

let a = box 1i;
let b = a;
// a cannot be used anymore, it has been moved
// following line would not compile
println!("{}", a);

但是值不能通过索引从向量中移出,因为它是返回的引用。

关于_ ,这段代码:

fn main() {
    let v = vec![box 1i];
    let _ = v[0];
    println!("{}", _);
}

产生此错误:

<anon>:4:20: 4:21 error: unexpected token: `_`
<anon>:4     println!("{}", _);
                            ^

_不是变量名,而是锈的特殊名称,告诉您不关心值,因此编译器不会尝试复制或移动任何东西。

您可以通过取消引用v [0]来使原始功能起作用:

fn main() {
    let v = vec![box 1i];
    let f = &v[0]; // notice the &
    println!("{}",f);
}

我不知道为什么下划线会使你的错误无声无息。 它应该引发错误,因为仅下划线是一个无效的变量名称(我认为)。 试图打印它会产生错误:

fn main() {
    let v = vec![box 1i];
    let _ = &v[0];
    println!("{}",_);
}

输出:

<anon>:4:19: 4:20 error: unexpected token: `_`
<anon>:4     println!("{}",_);

下划线被用来压制未使用的变量警告(例如,如果你定义some_var,从来没有使用它,编译器会骂你,但不会,如果你定义_some_var,从来没有使用它)。 它还用作匹配语句中的后备,以匹配与其他路径不匹配的任何内容:

fn main() {
    let v = vec![box 1i];
    let f = &v[0];
    match **f {
        3i => println!("{}",f),
        _ => println!("nothing here")
    };
}

比我聪明的人应评论下划线是否是有效的变量名称。 老实说,我认为编译器不应该允许它。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM