Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/rust/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Rust 在编译时,如何在不知道结构的情况下读取CSV数据?_Rust_Deserialization - Fatal编程技术网

Rust 在编译时,如何在不知道结构的情况下读取CSV数据?

Rust 在编译时,如何在不知道结构的情况下读取CSV数据?,rust,deserialization,Rust,Deserialization,我是个新手,还没开始尝试实现某种数据库。用户应该通过提供表名、列名向量和列类型向量(通过枚举实现)来创建表。填写表格时应指定csv文件。但是,这需要在编译时指定表行的结构,如基本示例所示: #[derive(Debug, Deserialize, Eq, PartialEq)] struct Row { key: u32, name: String, comment: String } use std::error::Error; use csv::ReaderBuild

我是个新手,还没开始尝试实现某种数据库。用户应该通过提供表名、列名向量和列类型向量(通过枚举实现)来创建表。填写表格时应指定csv文件。但是,这需要在编译时指定表行的结构,如基本示例所示:

#[derive(Debug, Deserialize, Eq, PartialEq)]
struct Row {
    key: u32,
    name: String,
    comment: String
}
use std::error::Error;
use csv::ReaderBuilder;
use serde::Deserialize;
use std::fs;

fn read_from_file(path: &str) -> Result<(), Box<dyn Error>> {
    let data = fs::read_to_string(path).expect("Unable to read file");
    let mut rdr = ReaderBuilder::new()
        .has_headers(false)
        .delimiter(b'|')
        .from_reader(data.as_bytes());
    let mut iter = rdr.deserialize();

    if let Some(result) = iter.next() {
        let record:Row = result?;
        println!("{:?}", record);
        Ok(())
    } else {
        Err(From::from("expected at least one record but got none"))
    }   
}
#[派生(调试、反序列化、Eq、PartialEq)]
结构行{
关键字:u32,
名称:String,
注释:String
}
使用std::error::error;
使用csv::ReaderBuilder;
使用serde::反序列化;
使用std::fs;
fn从\u文件读取\u(路径:&str)->结果{
让data=fs::read_to_string(path).expect(“无法读取文件”);
让mut rdr=ReaderBuilder::new()
.has_头(false)
.分隔符(b'|')
.from_reader(data.as_bytes());
让mut iter=rdr.deserialize();
如果让一些(结果)=iter.next(){
让记录:行=结果?;
println!(“{:?}”,记录);
好(())
}否则{
Err(From::From(“预期至少有一条记录,但没有记录”))
}   
}
是否有可能使用泛型表信息而不是“行”结构来强制转换反序列化的结果?是否可以简单地根据列类型的组合大小分配内存并解析中的记录?我会做这样的事情在C

是否有可能使用泛型表信息而不是“行”结构来强制转换反序列化的结果

所有泛型在编译时都替换为具体类型。如果您不知道运行时需要的类型,“泛型”不是您所需要的

是否可以简单地根据列类型的组合大小分配内存并解析中的记录?我会做这样的事情在C

我建议改为使用
Box
,以便能够存储任何类型的引用,并且仍然知道它是什么类型

这种方法的维护成本相当高。您必须在希望使用单元格值的任何位置管理每种可能的值类型。另一方面,您不需要每次都解析值,只需在运行时进行一些类型检查

我使用了
std::any::TypeId
来标识类型,但它不能用于
match
表达式中。可以考虑使用自定义枚举作为类型标识符。

使用std::any:{any,TypeId};
使用std::io::Read;
使用csv::Reader;
#[衍生(默认)]
结构表{
名称:String,
标题:Vec,
资料来源:Vec,
}
impl表格{
fn添加\头(&mut self,头:字符串,\类型:TypeId){
self.headers.push((header,_-type));
}
fn填充数据(
&莫特·赛尔夫,
rdr:&mut读取器,
)->结果{
对于rdr.records()中的记录{
让记录=记录?;
让mut行:Vec=Vec![];
对于self.headers.iter().zip(record.iter())中的(&(&,type_id),value){
如果type_id==TypeId::of::(){
row.push(Box::new(value.parse::()?);
}如果type_id==TypeId::of::(){
row.push(Box::new(value.to_owned());
}
}
self.data.push(行);
}
好(())
}
}
impl std::fmt::表的显示{

fn-fmt(&self,f:&mut std::fmt::Formatterserde_json有一个通用的
类型,它提供json的运行时动态构建和映射。有更多的解释。这可能是第一个要研究的方向。您的
结果
有一个类型,可以或多或少地作为字符串数组处理。@Jmb没错,我可以存储每一行作为字符串的向量,并在每次访问时转换为实际类型。但是,这似乎不是很有效。因此,您的问题不是关于CSV读取,而是“当类型仅在运行时已知时,如何存储不同类型的值?”然后,您希望对每种可能的类型使用带变体的。由于您是从CSV文件读取,因此您的所有值都将是
String
类型。插入时,特定类型可能会发生转换。您可以利用
from
特性来实现这一点。例如,如果表a需要值为
u32
类型,则您可以可以为u32执行
impl From
(这可能已经实现了..不确定)。在插入过程中,您可以执行
让值插入到表中。\u A:u32=string\u value.into();
您可以从
中阅读更多关于
的信息,这正是我要找的。肯定有“code”这里有开销,但性能可能更好。我计划在标题中的函数指针后面隐藏额外的代码复杂性。
通常应尽可能避免使用任何
。如果表只能包含有限的类型集(例如整数、浮点数或字符串),那么最好使用枚举。这避免了间接寻址,允许您简化某些操作(例如,您可以为枚举实现
Display
),并确保您不会忘记使用该值的代码中的类型。感谢您的提示。我将尝试这两种方法。