Rust:如何限制派生特征的类型参数
Rust: How to restrict type parameters for derived traits
我正在尝试编写一个通用函数,它采用指向 csv 文件的路径,将文件解析并反序列化为特定类型的记录向量和 returns 记录向量。
这是我的代码:
[dependencies]
csv = "1.1"
serde = { version = "1.0", features = ["derive"] }
首先是编译良好的特定类型版本:
use csv;
use serde::Deserialize;
use std::path::Path;
#[derive(Debug, Deserialize)]
struct Person {
name: String,
fav_colour: String,
}
#[derive(Debug, Deserialize)]
struct Car {
make: String,
year: u8,
}
fn main() {}
fn parse_csv(file_path: &Path) -> Vec<Person> {
// Create the csv reader
let mut csv_reader = csv::Reader::from_path(file_path).unwrap();
// Parse the csv and collect records
let records: Vec<Person> = csv_reader
.deserialize()
.map(|record: Result<Person, csv::Error>| {
record.expect(&format!("There was a problem parsing a line"))
})
.collect();
// Return records
records
}
parse_csv 函数适用于具体的 Person
结构。
我如何重写此函数,使其接受派生反序列化的通用 type/struct,例如,它可以接受 Person
或 Car
?
尝试失败:
fn parse_csv<T>(file_path: &Path) -> Vec<T> {
// Create the csv reader
let mut csv_reader = csv::Reader::from_path(file_path).unwrap();
// Parse the csv and collect records
let records: Vec<T> = csv_reader
.deserialize()
.map(|record: Result<T, csv::Error>| {
record.expect(&format!("There was a problem parsing a line"))
})
.collect();
// Return records
records
}
产生:
error[E0277]: the trait bound `for<'de> T: _::_serde::Deserialize<'de>` is not satisfied
--> src/main.rs:26:10
|
26 | .map(|record: Result<T, csv::Error>| {
| ^^^ the trait `for<'de> _::_serde::Deserialize<'de>` is not implemented for `T`
|
help: consider restricting this type parameter with `T: for<'de> _::_serde::Deserialize<'de>`
--> src/main.rs:19:14
|
19 | fn parse_csv<T>(file_path: &Path) -> Vec<T> {
| ^
= note: required because of the requirements on the impl of `_::_serde::de::DeserializeOwned` for `T`
= note: required because of the requirements on the impl of `std::iter::Iterator` for `csv::reader::DeserializeRecordsIter<'_, std::fs::File, T>`
编译器提示:
help: consider restricting this type parameter with `T: for<'de> _::_serde::Deserialize<'de>`
我该怎么做?
我对 Rust 比较陌生,在阅读了关于 traits
and the where
clause 的 Rust 书籍信息后(我怀疑答案就在这里),我仍然无法编译它。
您可以按照以下方式做一些事情:
use serde::de::DeserializeOwned;
fn parse_csv<T>(file_path: &Path) -> Vec<T>
where
T: DeserializeOwned,
{
/// deserialization logic
}
我正在尝试编写一个通用函数,它采用指向 csv 文件的路径,将文件解析并反序列化为特定类型的记录向量和 returns 记录向量。
这是我的代码:
[dependencies]
csv = "1.1"
serde = { version = "1.0", features = ["derive"] }
首先是编译良好的特定类型版本:
use csv;
use serde::Deserialize;
use std::path::Path;
#[derive(Debug, Deserialize)]
struct Person {
name: String,
fav_colour: String,
}
#[derive(Debug, Deserialize)]
struct Car {
make: String,
year: u8,
}
fn main() {}
fn parse_csv(file_path: &Path) -> Vec<Person> {
// Create the csv reader
let mut csv_reader = csv::Reader::from_path(file_path).unwrap();
// Parse the csv and collect records
let records: Vec<Person> = csv_reader
.deserialize()
.map(|record: Result<Person, csv::Error>| {
record.expect(&format!("There was a problem parsing a line"))
})
.collect();
// Return records
records
}
parse_csv 函数适用于具体的 Person
结构。
我如何重写此函数,使其接受派生反序列化的通用 type/struct,例如,它可以接受 Person
或 Car
?
尝试失败:
fn parse_csv<T>(file_path: &Path) -> Vec<T> {
// Create the csv reader
let mut csv_reader = csv::Reader::from_path(file_path).unwrap();
// Parse the csv and collect records
let records: Vec<T> = csv_reader
.deserialize()
.map(|record: Result<T, csv::Error>| {
record.expect(&format!("There was a problem parsing a line"))
})
.collect();
// Return records
records
}
产生:
error[E0277]: the trait bound `for<'de> T: _::_serde::Deserialize<'de>` is not satisfied
--> src/main.rs:26:10
|
26 | .map(|record: Result<T, csv::Error>| {
| ^^^ the trait `for<'de> _::_serde::Deserialize<'de>` is not implemented for `T`
|
help: consider restricting this type parameter with `T: for<'de> _::_serde::Deserialize<'de>`
--> src/main.rs:19:14
|
19 | fn parse_csv<T>(file_path: &Path) -> Vec<T> {
| ^
= note: required because of the requirements on the impl of `_::_serde::de::DeserializeOwned` for `T`
= note: required because of the requirements on the impl of `std::iter::Iterator` for `csv::reader::DeserializeRecordsIter<'_, std::fs::File, T>`
编译器提示:
help: consider restricting this type parameter with `T: for<'de> _::_serde::Deserialize<'de>`
我该怎么做?
我对 Rust 比较陌生,在阅读了关于 traits
and the where
clause 的 Rust 书籍信息后(我怀疑答案就在这里),我仍然无法编译它。
您可以按照以下方式做一些事情:
use serde::de::DeserializeOwned;
fn parse_csv<T>(file_path: &Path) -> Vec<T>
where
T: DeserializeOwned,
{
/// deserialization logic
}