You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在struct回调函数中使用外部对象(如CSV写入器)追加数据?

Alright, let's fix your Rust code step by step and get that Event data writing to CSV properly.

First, let's break down the errors you're seeing:

  • E0423: You tried to initialize the time field in Event::new with the SystemTime struct type itself, not the actual timestamp parameter t you passed in. That's a simple constructor mistake.
  • E0425: The wtr CSV writer lives in the main function's scope, but your Process::callback method can't access variables from outside its own scope. Rust enforces strict scope rules, so we need to pass the writer into the Process instance so it's available where we need it.

Here's the fully fixed code, followed by explanations of the key changes:

extern crate csv;
extern crate rand;

use rand::Rng;
use std::path::Path;
use std::time::{SystemTime, UNIX_EPOCH};

#[derive(Debug)]
struct Event {
    time: SystemTime,
    value: u32,
}

impl Event {
    fn new(t: SystemTime, n: u32) -> Event {
        // Fix: Use the passed-in timestamp `t` instead of the struct type
        Event { time: t, value: n }
    }
}

// Fix: Give Process ownership of the CSV writer so callback can access it
struct Process {
    wtr: csv::Writer<std::fs::File>,
}

impl Process {
    // Fix: Accept the CSV writer as a constructor parameter
    fn new(wtr: csv::Writer<std::fs::File>) -> Process {
        Process { wtr }
    }

    // Fix: Use &mut self because we need to modify the writer in callback
    fn start(&mut self) {
        loop {
            let now = SystemTime::now();
            let random_number: u32 = rand::thread_rng().gen();
            let event = Event::new(now, random_number);
            self.callback(event);
        }
    }

    // Fix: Use &mut self to mutate the internal writer
    fn callback(&mut self, event: Event) {
        println!("{:?}", event);
        
        // Fix: Convert Event fields to CSV-compatible strings
        // SystemTime can't be written directly, so we convert it to a UNIX timestamp (seconds)
        let timestamp = event.time
            .duration_since(UNIX_EPOCH)
            .unwrap_or_default() // Handle edge case where time is before UNIX epoch
            .as_secs();
        
        // Write the timestamp and value as a CSV record
        self.wtr.write_record(&[timestamp.to_string(), event.value.to_string()]).unwrap();
        self.wtr.flush().unwrap();
    }
}

fn main() {
    let file_path = Path::new("test.csv");
    let wtr = csv::Writer::from_path(file_path).unwrap();
    // Fix: Create Process with the writer, and mark it as mutable (since we'll modify it)
    let mut process: Process = Process::new(wtr);
    process.start();
}

Key Changes Explained:

  1. Fixed Event Constructor: Swapped SystemTime for the parameter t to properly initialize the time field with the actual timestamp.
  2. Attached Writer to Process: We added a wtr field to the Process struct, so the writer is now part of the process's state. This lets callback access it via self.wtr.
  3. Updated Method Mutability: Changed start and callback to take &mut self instead of &self—writing to the CSV writer requires a mutable reference, so the methods need permission to modify the Process instance.
  4. CSV-Compatible Formatting: Converted SystemTime to a UNIX timestamp string (since raw SystemTime can't be written to CSV) and formatted both fields as strings for the write_record method, which expects iterable string data.

Now when you run the code, it will generate random Events in a loop and append each one to your test.csv file.

内容的提问来源于stack exchange,提问作者Greg

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 09:27:08