如何在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
timefield inEvent::newwith theSystemTimestruct type itself, not the actual timestamp parametertyou passed in. That's a simple constructor mistake. - E0425: The
wtrCSV writer lives in themainfunction's scope, but yourProcess::callbackmethod can't access variables from outside its own scope. Rust enforces strict scope rules, so we need to pass the writer into theProcessinstance 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:
- Fixed Event Constructor: Swapped
SystemTimefor the parametertto properly initialize thetimefield with the actual timestamp. - Attached Writer to Process: We added a
wtrfield to theProcessstruct, so the writer is now part of the process's state. This letscallbackaccess it viaself.wtr. - Updated Method Mutability: Changed
startandcallbackto take&mut selfinstead of&self—writing to the CSV writer requires a mutable reference, so the methods need permission to modify theProcessinstance. - CSV-Compatible Formatting: Converted
SystemTimeto a UNIX timestamp string (since rawSystemTimecan't be written to CSV) and formatted both fields as strings for thewrite_recordmethod, 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
相关产品推荐
相关产品推荐

