为什么`&value.into_something()`仍然会导致移动值?

Dav*_*ner 0 rust

我很难看到这是如何转移所有权的.这是我的代码:

let res = screenshot::take_screenshot(0);
let file = File::open("test.png").expect("Failed to open file");

let encoder = PNGEncoder::new(file);
encoder.encode(&res.into_raw(), 
               res.width(),
               res.height(),
               ColorType::RGBA(0)
);
Run Code Online (Sandbox Code Playgroud)

screenshot::take_screenshot是一个返回的函数ImageBuffer<Rgba<u8>, Vec<u8>>.这是我得到的编译器错误:

error[E0382]: use of moved value: `res`
  --> src/main.rs:21:37
   |
21 |     encoder.encode(&res.into_raw(), res.width(), res.height(), ColorType::RGBA(0));
   |                     ---             ^^^ value used here after move
   |                     |
   |                     value moved here
   |
   = note: move occurs because `res` has type `image::ImageBuffer<image::Rgba<u8>, std::vec::Vec<u8>>`, which does not implement the `Copy` trait

error[E0382]: use of moved value: `res`
  --> src/main.rs:21:50
   |
21 |     encoder.encode(&res.into_raw(), res.width(), res.height(), ColorType::RGBA(0));
   |                     --- value moved here         ^^^ value used here after move
   |
   = note: move occurs because `res` has type `image::ImageBuffer<image::Rgba<u8>, std::vec::Vec<u8>>`, which does not implement the `Copy` trait
Run Code Online (Sandbox Code Playgroud)

我试图传递一个切片,我相信它是矢量的参考,不是吗?这意味着不会传递所有权,并且不会移动矢量.我知道我做错了什么,这可能很简单.

She*_*ter 5

这只是一个运算符优先级问题:方法在引用运算符之前应用&:

&(res.into_raw()) // This
(&res).into_raw() // Not this
Run Code Online (Sandbox Code Playgroud)

呼叫into_raw取得所有权,价值消失了.

你可以这样做:

let w = res.width();
let h = res.height();
let r = res.into_raw();
encoder.encode(&r, w, h, ColorType::RGBA(0));
Run Code Online (Sandbox Code Playgroud)

它可能有更好的东西,但你没有提供MCVE,因此很难迭代解决方案.盲目地从文档中猜测,它看起来应该有效:

extern crate image;

use image::{png::PNGEncoder, ColorType, ImageBuffer, Rgba};
use std::io;

fn repro<W: io::Write>(res: ImageBuffer<Rgba<u8>, Vec<u8>>, file: W) -> Result<(), io::Error> {
    let encoder = PNGEncoder::new(file);
    encoder.encode(&res, res.width(), res.height(), ColorType::RGBA(0))
}

fn main() {}
Run Code Online (Sandbox Code Playgroud)