在迭代中使用 Rust 中的通用 From-Trait
Use generic From-Trait in Rust in Iteration
我尝试编写一个简单的 postgres(=0.19.0) 查询函数,它将 Row 转换为我需要的 Type。
当我使用非通用类型时,它可以正常工作而不会出现编译错误:
#[derive(Clone, Debug)]
struct Entry {
id: u32,
value: u32,
}
impl<'a> From<&'a Row> for Entry {
fn from(row: &'a Row) -> Self {
Entry {
id: row.get(0),
value: row.get(1),
}
}
}
fn query<'a, T: FromSql<'a>>(client: &mut Client, query_str: &str, params: &[&(dyn ToSql + Sync)]) -> Vec<Entry> {
client.query(query_str, params)
.map(|rows| {
rows
.iter()
.map(|r| {
Entry::from(r)
})
.collect()
})
.unwrap_or(vec![] as Vec<Entry>)
}
当我尝试以通用方式转换相同的逻辑时,出现编译错误。
fn query<'a, T: From<&'a Row>>(client: &mut Client, query_str: &str, params: &[&(dyn ToSql + Sync)]) -> Vec<T> {
let rows = client.query(query_str, params)
.unwrap_or(vec![] as Vec<Row>);
rows
.iter()
.map(|r: &'a Row| {
T::from(r)
})
.collect()
}
我会说逻辑是相等的,我看不出有什么不同,但是生命周期定义不正确。
我是不是错过了一个特质或类似的东西?
|
238 | fn query<'a, T: From<&'a Row>>(client: &mut Client, query_str: &str, params: &[&(dyn ToSql + Sync)]) -> Vec<T> {
| -- lifetime `'a` defined here
...
241 | rows
| ^^^^ borrowed value does not live long enough
...
244 | T::from(r)
| ---------- argument requires that `rows` is borrowed for `'a`
...
247 | })
| - `rows` dropped here while still borrowed
编辑:
我将代码简化为这个例子,也许它更有帮助。
fn convert<'a, T: From<&'a abc>>() -> Vec<T> {
let abcs = vec![abc::new(), abc::new(), abc::new(), abc::new()];
abcs
.iter()
.map(|f| {
T::from(f)
})
.collect()
}
这里是错误:
error[E0597]: `abcs` does not live long enough
--> src/main.rs:43:5
|
41 | fn convert<'a, T: From<&'a abc>>() -> Vec<T> {
| -- lifetime `'a` defined here
42 | let abcs = vec![abc::new(), abc::new(), abc::new(), abc::new()];
43 | abcs
| ^^^^ borrowed value does not live long enough
...
46 | T::from(f)
| ---------- argument requires that `abcs` is borrowed for `'a`
...
49 | }
| - `abcs` dropped here while still borrowed
我一直想找出问题所在,但我做不到。您是否尝试查找任何拼写错误?我不明白代码,但我给你答案的原因是因为我的朋友可能会理解它。好吧,所以他说你可能错过了一个特征,但他不能说出是哪个特征或问题是什么。他建议查看一下,我以前忘记在我的程序中添加代码,并且拼写错误。查看我的代码几乎总是对我有帮助。
当您指定
fn convert<'a, T: From<&'a abc>>() -> Vec<T>
你基本上是在断言 T
只为那些 abc
的引用实现 From<&abc>
,这些引用的生命周期 超过 函数。
您可以假设您的函数具有以下隐式生命周期(此处以伪代码表示):
fn convert<'a, T: From<&'a abc>>() -> Vec<T> {
'b : {
let abcs = vec![abc::new(), abc::new(), abc::new(), abc::new()];
abcs
.iter()
.map(|f| {
T::from(f)
})
.collect()
}
}
abcs
属于隐式生命周期 "'b",它小于 'a
,因此不能引用其中一个元素满足From<&'a abc>>
。鉴于您 必须 在约束 T: From<&'a abc>
时指定生命周期,没有简单的方法可以解决这个问题。
编译器拒绝此代码是有意义的,因为它无法确保 T: From<&'a abc>
中的 From::from
不会生成不包含其引用的 T创建自。
你的函数也会接受类似下面的内容
struct X<'a> {
r: &' abc
}
impl <'a> From<&'a abc> for X<'a> {
fn from(r: &'a abc) -> Self {
Self { r }
}
}
但由于 convert
返回包含对 abc
.
的本地实例的引用的 Vec<X>
,它会被破坏
您正在寻找的是所谓的“高级特征绑定”。 (参见 here)
for<'a> can be read as "for all choices of 'a", and basically produces an infinite list of trait bounds that F must satisfy
这似乎是您想要的,因为您可以指定比 convert
的生命周期“更小”的生命周期。
在您的示例中,这看起来像:
fn convert< T: for<'a> From<&'a abc>>() -> Vec<T> {
let abcs = vec![abc::new(), abc::new(), abc::new(), abc::new()];
abcs
.iter()
.map(|f| {
T::from(f)
})
.collect()
}
我尝试编写一个简单的 postgres(=0.19.0) 查询函数,它将 Row 转换为我需要的 Type。
当我使用非通用类型时,它可以正常工作而不会出现编译错误:
#[derive(Clone, Debug)]
struct Entry {
id: u32,
value: u32,
}
impl<'a> From<&'a Row> for Entry {
fn from(row: &'a Row) -> Self {
Entry {
id: row.get(0),
value: row.get(1),
}
}
}
fn query<'a, T: FromSql<'a>>(client: &mut Client, query_str: &str, params: &[&(dyn ToSql + Sync)]) -> Vec<Entry> {
client.query(query_str, params)
.map(|rows| {
rows
.iter()
.map(|r| {
Entry::from(r)
})
.collect()
})
.unwrap_or(vec![] as Vec<Entry>)
}
当我尝试以通用方式转换相同的逻辑时,出现编译错误。
fn query<'a, T: From<&'a Row>>(client: &mut Client, query_str: &str, params: &[&(dyn ToSql + Sync)]) -> Vec<T> {
let rows = client.query(query_str, params)
.unwrap_or(vec![] as Vec<Row>);
rows
.iter()
.map(|r: &'a Row| {
T::from(r)
})
.collect()
}
我会说逻辑是相等的,我看不出有什么不同,但是生命周期定义不正确。
我是不是错过了一个特质或类似的东西?
|
238 | fn query<'a, T: From<&'a Row>>(client: &mut Client, query_str: &str, params: &[&(dyn ToSql + Sync)]) -> Vec<T> {
| -- lifetime `'a` defined here
...
241 | rows
| ^^^^ borrowed value does not live long enough
...
244 | T::from(r)
| ---------- argument requires that `rows` is borrowed for `'a`
...
247 | })
| - `rows` dropped here while still borrowed
编辑:
我将代码简化为这个例子,也许它更有帮助。
fn convert<'a, T: From<&'a abc>>() -> Vec<T> {
let abcs = vec![abc::new(), abc::new(), abc::new(), abc::new()];
abcs
.iter()
.map(|f| {
T::from(f)
})
.collect()
}
这里是错误:
error[E0597]: `abcs` does not live long enough
--> src/main.rs:43:5
|
41 | fn convert<'a, T: From<&'a abc>>() -> Vec<T> {
| -- lifetime `'a` defined here
42 | let abcs = vec![abc::new(), abc::new(), abc::new(), abc::new()];
43 | abcs
| ^^^^ borrowed value does not live long enough
...
46 | T::from(f)
| ---------- argument requires that `abcs` is borrowed for `'a`
...
49 | }
| - `abcs` dropped here while still borrowed
我一直想找出问题所在,但我做不到。您是否尝试查找任何拼写错误?我不明白代码,但我给你答案的原因是因为我的朋友可能会理解它。好吧,所以他说你可能错过了一个特征,但他不能说出是哪个特征或问题是什么。他建议查看一下,我以前忘记在我的程序中添加代码,并且拼写错误。查看我的代码几乎总是对我有帮助。
当您指定
fn convert<'a, T: From<&'a abc>>() -> Vec<T>
你基本上是在断言 T
只为那些 abc
的引用实现 From<&abc>
,这些引用的生命周期 超过 函数。
您可以假设您的函数具有以下隐式生命周期(此处以伪代码表示):
fn convert<'a, T: From<&'a abc>>() -> Vec<T> {
'b : {
let abcs = vec![abc::new(), abc::new(), abc::new(), abc::new()];
abcs
.iter()
.map(|f| {
T::from(f)
})
.collect()
}
}
abcs
属于隐式生命周期 "'b",它小于 'a
,因此不能引用其中一个元素满足From<&'a abc>>
。鉴于您 必须 在约束 T: From<&'a abc>
时指定生命周期,没有简单的方法可以解决这个问题。
编译器拒绝此代码是有意义的,因为它无法确保 T: From<&'a abc>
中的 From::from
不会生成不包含其引用的 T创建自。
你的函数也会接受类似下面的内容
struct X<'a> {
r: &' abc
}
impl <'a> From<&'a abc> for X<'a> {
fn from(r: &'a abc) -> Self {
Self { r }
}
}
但由于 convert
返回包含对 abc
.
Vec<X>
,它会被破坏
您正在寻找的是所谓的“高级特征绑定”。 (参见 here)
for<'a> can be read as "for all choices of 'a", and basically produces an infinite list of trait bounds that F must satisfy
这似乎是您想要的,因为您可以指定比 convert
的生命周期“更小”的生命周期。
在您的示例中,这看起来像:
fn convert< T: for<'a> From<&'a abc>>() -> Vec<T> {
let abcs = vec![abc::new(), abc::new(), abc::new(), abc::new()];
abcs
.iter()
.map(|f| {
T::from(f)
})
.collect()
}