【问题标题】:How to handle "use of moved value in previous iteration of loop" when writing to a BufWriter?写入 BufWriter 时如何处理“在循环的前一次迭代中使用移动的值”?
【发布时间】:2021-03-20 08:36:34
【问题描述】:

我遇到以下代码错误:

use std::fs::File;
use std::io::{BufWriter, Write};

fn mandel_color(i: f32, mut writer: BufWriter<&File>) {
    let ir = 16.0 * (i % 15.0);
    let ig = 32.0 * (i % 7.0);
    let ib = 8.0*(i % 31.0);
    write!(&mut writer, "{} {} {}\n", ir, ig, ib).expect("unable to write to file.");
}

fn mandel_iter(cx: f32, cy: f32) -> f32 {
    let mut pair = (0.0, 0.0);
    let mut count = 0.0;
    while f32::sqrt(f32::powf(pair.0,2.0) + f32::powf(pair.1,2.0)) < 2.0 && count < 255.0 {
        pair = ((f32::powf(pair.0,2.0) - f32::powf(pair.1,2.0) + cx), (2.0*pair.0*pair.1 + cy));
        count += 1.0;
    }
    count
}

fn mandelbrot(width: i32, height: i32) {
    let file = File::create("img/image.ppm").expect("unable to create image.ppm");
    let mut writer = BufWriter::new(&file);
    write!(&mut writer, "P3\n{} {}\n255\n", width, height).expect("unable to write to file.");
    for x in 0..width {
        for j in 0..height {
            let x_ish = ((x as f32 - width as f32 * 11.0/15.0) / (width as f32 /3.0)) as f32;
            let y_ish = ((j as f32- height as f32 * 2.0) / (height as f32 * 3.0/10.0)) as f32;
            // how do i fix the error with writer here?
            mandel_color(mandel_iter(x_ish, y_ish), writer);
        }
    }
}

fn main() {
     const IMAGE_WIDTH: i32 = 256;
     const IMAGE_HEIGHT: i32 = 256;
     mandelbrot(IMAGE_HEIGHT, IMAGE_WIDTH);
}
error[E0382]: use of moved value: `writer`
  --> src/main.rs:32:53
   |
25 |      let mut writer = BufWriter::new(&file);
   |          ---------- move occurs because `writer` has type `BufWriter<&File>`, which does not implement the `Copy` trait
...
32 |             mandel_color(mandel_iter(x_ish, y_ish), writer);
   |                                                     ^^^^^^ value moved here, in previous iteration of loop

Link to playground

我尝试使用#[derive(Copy)]Writer 设置结构,但BufWriter&lt;&amp;File&gt; 无法实现Copy 特征...所以我不确定应该如何处理这种情况...

如何处理循环中的移动值?特别是这部分:

mandel_color(mandel_iter(x_ish, y_ish), writer);

【问题讨论】:

  • 根据实现你不需要mandel_color中作者的所有权,它应该这样定义:fn mandel_color(i: f32, writer: &amp;mut BufWriter&lt;&amp;File&gt;)Playground.
  • 这是一个错字(调试)。但是您的解决方案正是我所需要的。谢谢。

标签: rust


【解决方案1】:

您的原始代码将值移动到mandel_color(),这意味着不仅调用者无法继续使用它,而且mandel_color 将拥有写入器,因此一旦写入单个三元组和writer 就关闭它超出范围。这种所有权转让肯定不是有意的。

您可以通过不移动值来防止所有权转移并修复“移动值”错误,在这种情况下,只需让mandel_color 接受对作者的引用

fn mandel_color(i: f32, writer: &mut BufWriter<&File>) {
    let ir = 16.0 * (i % 15.0);
    let ig = 32.0 * (i % 7.0);
    let ib = 8.0 * (i % 31.0);
    write!(writer, "{} {} {}\n", ir, ig, ib).expect("unable to write to file.");
}

调整调用站点以获取参考:

mandel_color(mandel_iter(x_ish, y_ish), &mut writer);

您还可以通过使mandel_color 与实现Write 特征的任何 类型一起使用来使mandel_color 更通用(不会损失性能)。这样您就不必拼出确切的类型BufWriter&lt;&amp;File&gt;,并且您的代码将在写入网络套接字、标准输出、内存等的输出上保持不变:

fn mandel_color(i: f32, mut writer: impl Write) {
    let ir = 16.0 * (i % 15.0);
    let ig = 32.0 * (i % 7.0);
    let ib = 8.0 * (i % 31.0);
    write!(writer, "{} {} {}\n", ir, ig, ib).expect("unable to write to file.");
}

Playground

【讨论】:

    猜你喜欢
    • 2023-04-10
    • 2022-08-17
    • 1970-01-01
    • 1970-01-01
    • 2020-03-03
    • 1970-01-01
    • 2021-04-19
    • 2020-07-12
    • 1970-01-01
    相关资源
    最近更新 更多