Rust “无法使用向量移出解除引用`&`-pointer”

Rust “无法使用向量移出解除引用`&`-pointer”,rust,Rust,我现在正在尝试生锈,我真的被各种各样的随机编译器错误绊倒了,比如: error: cannot move out of dereference of `&`-pointer return list[idx]; ^~~~~~~~~ 下面是有问题的片段。list是一个单词列表,其思想是从列表中返回一个在minLength和maxLength之间一定长度内的随机单词。因此,我生成一个随机uint,并使用模将其约束到列表的大小。然后我想检查这个单词的长度是否正确,

我现在正在尝试生锈,我真的被各种各样的随机编译器错误绊倒了,比如:

error: cannot move out of dereference of `&`-pointer
    return list[idx];
           ^~~~~~~~~
下面是有问题的片段。list是一个单词列表,其思想是从列表中返回一个在minLength和maxLength之间一定长度内的随机单词。因此,我生成一个随机uint,并使用模将其约束到列表的大小。然后我想检查这个单词的长度是否正确,是否正确,并返回它

显然,这不是最有效的方法,但我只是想要一些简单的方法来满足练习的需要

fn get_a_word(list: Vec<String>, minLength: uint, maxLength: uint) -> String {
    loop {
        let idx = rand::random::<uint>() % list.len();
        if list[idx].len() > minLength && list[idx].len() < maxLength {
            return list[idx];
        }
    }
}
我对这个错误消息的含义做了一些研究,但每个人似乎都说,当你处理选项回收时,而不是试图从集合中获取值时,就会出现这个错误消息

这可能是一个非常简单的问题,但为什么Rust不让您从集合/向量/数组返回值呢?

list[idx]是*list.index&idx的缩写。返回在此处索引的值Vec内借用的指针。不能通过取消引用借用的指针来移动此处的值或字符串;这就像从拥有该字符串的Vec中窃取字符串一样。字符串拥有堆上的分配;我们不能有两个引用相同堆分配的字符串值,否则它们在被丢弃时都会尝试释放,这将导致双重释放

由于函数按值接收Vec,这意味着Vec被移动到函数中,因此函数可以对其执行任何操作,因为它现在拥有Vec,所以当函数退出时,Vec将被销毁。例如,我们可以删除要从Vec返回的字符串,以便Vec不再拥有该字符串的所有权

如果必须绝对返回字符串,则可以克隆该值:

fn get_a_word(list: &Vec<String>, minLength: uint, maxLength: uint) -> String {
    loop {
        let idx = rand::random::<uint>() % list.len();
        if list[idx].len() > minLength && list[idx].len() < maxLength {
             return list[idx].clone();
        }
    }
}
list[idx]是*list.index&idx的缩写。返回在此处索引的值Vec内借用的指针。不能通过取消引用借用的指针来移动此处的值或字符串;这就像从拥有该字符串的Vec中窃取字符串一样。字符串拥有堆上的分配;我们不能有两个引用相同堆分配的字符串值,否则它们在被丢弃时都会尝试释放,这将导致双重释放

由于函数按值接收Vec,这意味着Vec被移动到函数中,因此函数可以对其执行任何操作,因为它现在拥有Vec,所以当函数退出时,Vec将被销毁。例如,我们可以删除要从Vec返回的字符串,以便Vec不再拥有该字符串的所有权

如果必须绝对返回字符串,则可以克隆该值:

fn get_a_word(list: &Vec<String>, minLength: uint, maxLength: uint) -> String {
    loop {
        let idx = rand::random::<uint>() % list.len();
        if list[idx].len() > minLength && list[idx].len() < maxLength {
             return list[idx].clone();
        }
    }
}

一次只能拥有一个对象,您在那里尝试的操作将打破该不变量,因为您将在向量和返回位置返回字符串。list[idx]或多或少地扩展为*list.indexix对于该方法来说,事实上它比这个复杂一点,因为它应该是Index::Index还是IndexMut::Index_mut取决于上下文,&list[idx]将只是一个直接的list.indexix和list[idx]。自取方法的方法将是list.indexix.method

你有几个选择;以下是三点:

从列表中删除该值并返回它。剩下的Vec将被删除,因此除了右边的字符串之外的所有字符串最终都将被释放

返回list.swap_removiedx.unwrap;与和相比,前者效率更高,但改变了顺序,在本例中,顺序完全可以代替返回列表[idx];我可以帮你

克隆字符串。这效率较低,但可能被认为是可以接受的

返回列表[idx]。克隆;我就可以了

在整个过程中使用切片和引用:这是最有效的方法,通常也是最惯用的方法。它的效率很高,因为它不涉及任何分配或解除分配或移动大值

fn get_a_word(list: &[String], min_length: uint, max_length: uint) -> &str {
    loop {
        let idx = rand::random::<uint>() % list.len();
        if list[idx].len() > min_length && list[idx].len() < max_length {
            return list[idx].as_slice();
        }
    }
}

一次只能拥有一个对象,您在那里尝试的操作将打破该不变量,因为您将在向量和返回位置返回字符串。list[idx]或多或少地扩展为*list.indexix对于该方法来说,事实上它比这个复杂一点,因为它应该是Index::Index还是IndexMut::Index_mut取决于上下文,&list[idx]将只是一个直接的list.indexix和list[idx]。自取方法的方法将是list.indexix.method

你有几个选择;以下是三点:

从列表中删除该值并返回它。剩下的Vec将被删除,因此除了右边的字符串之外的所有字符串最终都将被释放< /p> 返回list.swap_removiedx.unwrap;与和相比,前者效率更高,但改变了顺序,在本例中,顺序完全可以代替返回列表[idx];我可以帮你

克隆字符串。这效率较低,但可能被认为是可以接受的

返回列表[idx]。克隆;我就可以了

在整个过程中使用切片和引用:这是最有效的方法,通常也是最惯用的方法。它的效率很高,因为它不涉及任何分配或解除分配或移动大值

fn get_a_word(list: &[String], min_length: uint, max_length: uint) -> &str {
    loop {
        let idx = rand::random::<uint>() % list.len();
        if list[idx].len() > min_length && list[idx].len() < max_length {
            return list[idx].as_slice();
        }
    }
}

如何快速判断列表[idx]扩展为*list.index[&idx]?虽然我同意这样做是有道理的,但我找不到相关文档。事实上,您发布的文档中的函数定义fn index&'a self,index:Idx->&'a self::Output似乎并不要求该索引是引用。@mSSM:从那时起,它从按引用获取索引改为按值获取索引。现在,list[index]相当于*list.indexindex或list.indexindex或list.index\u mutindex,具体取决于它的使用方式&list[index]是标准形式,表示list.indexindex,因此将list[index]设为*list.indexindex是有意义的。它还受自动引用规则的约束,所以list[index]。通过\ u ref获取\ u self的方法\等同于&list[index]。通过\ u ref获取\ u self的方法\如何快速判断list[idx]扩展为*list.index[&idx]?虽然我同意这样做是有道理的,但我找不到相关文档。事实上,您发布的文档中的函数定义fn index&'a self,index:Idx->&'a self::Output似乎并不要求该索引是引用。@mSSM:从那时起,它从按引用获取索引改为按值获取索引。现在,list[index]相当于*list.indexindex或list.indexindex或list.index\u mutindex,具体取决于它的使用方式&list[index]是标准形式,表示list.indexindex,因此将list[index]设为*list.indexindex是有意义的。它还受自动引用规则的约束,因此list[index]。通过\u-ref获取\u-self的方法\u与通过\u-ref获取\u-self的方法\u等效于&list[index]。通过\u-ref获取\u-self的方法\u。