我的理解是在范围外创建的对象在范围内可用(因此允许诸如阴影之类的东西),但在这种情况下它似乎不起作用:
extern crate csv;
extern crate rand;
use rand::Rng;
use std::path::Path;
use std::time::SystemTime;
#[derive(Debug)]
struct Event {
time: SystemTime,
value: u32,
}
impl Event {
fn new(t: SystemTime, n: u32) -> Event {
Event {
time: SystemTime,
value: n,
}
}
}
struct Process;
impl Process {
fn new() -> Process {
Process {}
}
fn start(&self) {
loop {
let now = SystemTime::now();
let random_number: u32 = rand::thread_rng().gen();
let event = Event::new(now, random_number);
self.callback(event);
}
}
fn callback(&self, event: Event) {
println!("{:?}", event);
wtr.write_record(&event).unwrap();
wtr.flush().unwrap();
}
}
fn main() {
let file_path = Path::new("test.csv");
let mut wtr = csv::Writer::from_path(file_path).unwrap();
let process: Process = Process::new();
process.start();
}
错误是:
error[E0423]: expected value, found struct `SystemTime`
--> src/main.rs:17:19
|
17 | time: SystemTime,
| ^^^^^^^^^^ constructor is not visible here due to private fields
error[E0425]: cannot find value `wtr` in this scope
--> src/main.rs:41:9
|
41 | wtr.write_record(&event).unwrap();
| ^^^ not found in this scope
error[E0425]: cannot find value `wtr` in this scope
--> src/main.rs:42:9
|
42 | wtr.flush().unwrap();
| ^^^ not found in this scope
如何从 Process
的回调函数中将数据(Event
)附加到 CSV 文件?
最佳答案
我强烈鼓励您回去重新阅读The Rust Programming Language ,特别是关于functions的章节.此代码似乎显示了围绕函数工作方式的整个模型的基本问题。
例如,代码试图在函数 callback
中使用变量 wtr
,而不是直接或间接传入它。
如果这样的代码有效1,程序员可能会讨厌与这种语言打交道,因为几乎不可能告诉什么和在哪里值 wtr
甚至来自。
解决方案很简单:将一段代码需要的任何值传递给该代码。这样就很容易(或更容易)分辨出值(value)的来源。有多种途径可以发挥作用。
将参数传递给
callback
方法:use std::io::Write; impl Process { fn start<R>(&self, wtr: &mut csv::Writer<R>) where R: Write, { loop { // ... self.callback(wtr, event); } } fn callback<R>(&self, wtr: &mut csv::Writer<R>, event: Event) where R: Write, { // ... } } fn main() { // ... process.start(&mut wtr); }
将参数传递给构造函数并将其保存在结构中:
use std::io::Write; struct Process<'a, R> where R: Write + 'a, { wtr: &'a mut csv::Writer<R>, } impl<'a, R> Process<'a, R> where R: Write, { fn new(wtr: &'a mut csv::Writer<R>) -> Self { Process { wtr } } // ... fn callback(&self, event: Event) { // ... self.wtr.write_record(event).unwrap(); self.wtr.flush().unwrap(); } } fn main() { // ... let process = Process::new(&mut wtr); }
代码在如何使用 CSV 库方面还有其他问题,我忽略了这些问题,因为它们与您的问题无关。我鼓励您从一段更简单的代码开始,让它运行起来,然后再让它变得更复杂。这样一开始您只会处理更简单的错误。
了解了函数的基本用法后,您可能希望了解 closures .这些允许您从外部范围“捕获”变量并将它们传入(使用与上述相同的两种方法),而无需处理特定数量或类型的变量。
objects created outside of the scope are available inside the scope
对于单个函数来说是这样。它不适用于跨函数。
hence things such as shadowing allowed
阴影与范围无关。您可以在同一范围内进行阴影:
let a = Some(32);
let a = a.unwrap();
1。这样的语言存在;它们是带有 dynamic scope 的语言有些人更喜欢它们。他们是少数,用这些语言编写的程序很难推理!
关于csv - 如何在结构回调中使用外部对象,例如将数据附加到 CSV 时?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50462046/