Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/wix/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Rust 可以通过获取可变引用来移动值吗?_Rust - Fatal编程技术网

Rust 可以通过获取可变引用来移动值吗?

Rust 可以通过获取可变引用来移动值吗?,rust,Rust,pub-trait-Skip{ fn跳过(&mut self,步骤:usize); } 为我请求跳过{ fn跳过(&mut self,mut步骤:usize){ 为了自己{ 步骤-=1; 如果步骤:20:22 19 |>字符跳过(2); |>----值移到了这里 20 |>println!(“{:?}”,chars.collect::()); |>^^^^^移动后此处使用的值 :20:22:20:27:注意:在格式的扩展中_args! :20:22:20:27:注意:在此打印扩展中!(在中定义)

pub-trait-Skip{
fn跳过(&mut self,步骤:usize);
}
为我请求跳过{
fn跳过(&mut self,mut步骤:usize){
为了自己{
步骤-=1;
如果步骤:20:22
19 |>字符跳过(2);
|>----值移到了这里
20 |>println!(“{:?}”,chars.collect::());
|>^^^^^移动后此处使用的值
:20:22:20:27:注意:在格式的扩展中_args!
:20:22:20:27:注意:在此打印扩展中!(在中定义)
:20:22:20:27:注意:在此println!(在中定义)的扩展中
注意:发生移动是因为'chars'具有'std::str::chars'类型
可以通过获取可变引用来移动值吗

不。引用不会移动引用的项目。这是一个很大的引用点

但是,它确实拥有迭代器的所有权,这是一种移动:

fn skip(self, n: usize) -> Skip<Self>
但是,请注意,不使用迭代器适配器调用迭代器适配器不会产生任何效果:

警告:必须使用未使用的结果:迭代器适配器是惰性的,除非已使用,否则不会执行任何操作

这里真正的问题是,您没有调用您认为是的
skip
。如果您将方法重命名为
skip2
,您将看到它按预期工作

这是因为方法查找优先选择先按值(
self
)再按引用(
&self
)再按可变引用(
&mut self
)接受接收方的方法

选择与标准库相同的方法名可能是一个坏主意,尤其是对于迭代器,但是非常令人惊讶的是,没有打印一条警告,指出范围内有多个适用的方法

您可以使用指定要调用的实现:

pub trait Skip: Iterator {
    fn skip(&mut self, steps: usize) {
        for _ in self.take(steps) {}
    }
}

impl<I> Skip for I where I: Iterator {}

fn main() {
    let s  = "abc123def";
    let mut chars = s.chars();
    Skip::skip(&mut chars, 2);
    println!("{:?}", chars.collect::<String>());
}
pub-trait-Skip:迭代器{
fn跳过(多个自身,步骤:usize)(&M){
为{in self.采取(步骤){}
}
}
I的impl Skip,其中I:Iterator{}
fn main(){
设s=“abc123def”;
设mut chars=s.chars();
跳过::跳过(&多个字符,2);
println!(“{:?}”,chars.collect::());
}

如果将
Skip::Skip
更改为直接获取
I
,或者在mut引用上调用它(例如,
(&mut chars)。Skip(2)
)。否则它是合法的原因是,
Iterator
的方法不需要autoref,因此它更具体,因此更可取。
rustc
中的lint非常简单,但可能clippy对此有一个lint。@delnan我想知道是否有一个选择方法的顺序(
self
then
&self
then
&mut self
)和“多种适用方法”只有在同一个类中有多个方法时才会发生错误?@Shepmaster我认为这是根据是否需要autoref来表述的,但基本上是肯定的。答案解释了为什么这不起作用以及如何解决它,但老实说,很可能最好只使用stdlib的
skip
,即使它的API(它是一个迭代器适配器,而不是一个变异的方法)。@delnan经过一些变异迭代器的实验后,我同意!
chars.by_ref().skip(2);
pub trait Skip: Iterator {
    fn skip(&mut self, steps: usize) {
        for _ in self.take(steps) {}
    }
}

impl<I> Skip for I where I: Iterator {}

fn main() {
    let s  = "abc123def";
    let mut chars = s.chars();
    Skip::skip(&mut chars, 2);
    println!("{:?}", chars.collect::<String>());
}