这个更高级别的特征界限是什么意思?
What does this higher-ranked trait bound mean?
在 Salsa 中,有一个更高级别的特征绑定到一个特征上。我在功能定义上看到了 HRTB,但在特征上没有看到。这是什么意思?
pub trait Query: Debug + Default + Sized + for<'d> QueryDb<'d> {
...
fn query_storage<'a>(
group_storage: &'a <Self as QueryDb<'_>>::GroupStorage,
) -> &'a Arc<Self::Storage>;
}
https://github.com/salsa-rs/salsa/blob/fc6806a/src/lib.rs#L370
如题,我该如何阅读?是不是说,对于任何 Query
,都有一个对应的 QueryDB
有 一些 生命周期?
这与
有何不同
pub trait Query<'d>: Debug + Default + Sized + QueryDb<'d>
除此之外,impls 无法指定 'd
?
与query_storage
的参数类型有关:
Self as QueryDb<'_>
来自小说:
for<'a>
can be read as "for all choices of 'a", and basically produces an infinite list of trait bounds that F must satisfy.
how should I read this?
这意味着 Query
的任何实现也同时为 'd
的所有可能值(即所有生命周期)实现 QueryDb<'d>
.因此,在一般情况下,特征界限 T: Query
意味着 T: for<'d> QueryDb<'d>
.
How is this different from
pub trait Query<'d>: Debug + Default + Sized + QueryDb<'d>
aside from that impls cannot specify 'd
?
通过在 Query
上重复生命周期参数,这意味着所有特征边界 T: Query
都需要更改为 T: for<'d> Query<'d>
以等效于 HRTB 所在的版本在 Query
本身。
这基本上就是a workaround for the lack of generic associated types。对于泛型关联类型,QueryDb
看起来像这样:
pub trait QueryDb: Sized {
/// Dyn version of the associated trait for this query group.
type DynDb<'d>: ?Sized + Database + HasQueryGroup<Self::Group> + 'd;
/// Associate query group struct.
type Group: plumbing::QueryGroup<GroupStorage = Self::GroupStorage>;
/// Generated struct that contains storage for all queries in a group.
type GroupStorage;
}
在引入此生命周期参数的 pull request 之前,QueryDb
不是一个单独的特征;它的成员是 Query
的一部分。通用关联类型将允许我们将 QueryDb
合并回 Query
.
在阅读了关于那个 pull request 的评论后,我觉得这个改变没有产生预期的结果。目标是在关联类型 DynDb
上允许与隐含的 'static
不同的界限,但是由于每个 Query
为所有可能的 'd
实现 QueryDb<'d>
,这意味着每个 Query
实施 QueryDb<'static>
。因此,在 QueryDb
的所有实现中,DynDb
不可能借用任何生命周期短于 'static
的东西,否则 Query
的实现将不被允许(边界for<'d> QueryDb<'d>
不会满意)。
在 Salsa 中,有一个更高级别的特征绑定到一个特征上。我在功能定义上看到了 HRTB,但在特征上没有看到。这是什么意思?
pub trait Query: Debug + Default + Sized + for<'d> QueryDb<'d> {
...
fn query_storage<'a>(
group_storage: &'a <Self as QueryDb<'_>>::GroupStorage,
) -> &'a Arc<Self::Storage>;
}
https://github.com/salsa-rs/salsa/blob/fc6806a/src/lib.rs#L370
如题,我该如何阅读?是不是说,对于任何 Query
,都有一个对应的 QueryDB
有 一些 生命周期?
这与
有何不同pub trait Query<'d>: Debug + Default + Sized + QueryDb<'d>
除此之外,impls 无法指定 'd
?
与query_storage
的参数类型有关:
Self as QueryDb<'_>
来自小说:
for<'a>
can be read as "for all choices of 'a", and basically produces an infinite list of trait bounds that F must satisfy.
how should I read this?
这意味着 Query
的任何实现也同时为 'd
的所有可能值(即所有生命周期)实现 QueryDb<'d>
.因此,在一般情况下,特征界限 T: Query
意味着 T: for<'d> QueryDb<'d>
.
How is this different from
pub trait Query<'d>: Debug + Default + Sized + QueryDb<'d>
aside from that impls cannot specify
'd
?
通过在 Query
上重复生命周期参数,这意味着所有特征边界 T: Query
都需要更改为 T: for<'d> Query<'d>
以等效于 HRTB 所在的版本在 Query
本身。
这基本上就是a workaround for the lack of generic associated types。对于泛型关联类型,QueryDb
看起来像这样:
pub trait QueryDb: Sized {
/// Dyn version of the associated trait for this query group.
type DynDb<'d>: ?Sized + Database + HasQueryGroup<Self::Group> + 'd;
/// Associate query group struct.
type Group: plumbing::QueryGroup<GroupStorage = Self::GroupStorage>;
/// Generated struct that contains storage for all queries in a group.
type GroupStorage;
}
在引入此生命周期参数的 pull request 之前,QueryDb
不是一个单独的特征;它的成员是 Query
的一部分。通用关联类型将允许我们将 QueryDb
合并回 Query
.
在阅读了关于那个 pull request 的评论后,我觉得这个改变没有产生预期的结果。目标是在关联类型 DynDb
上允许与隐含的 'static
不同的界限,但是由于每个 Query
为所有可能的 'd
实现 QueryDb<'d>
,这意味着每个 Query
实施 QueryDb<'static>
。因此,在 QueryDb
的所有实现中,DynDb
不可能借用任何生命周期短于 'static
的东西,否则 Query
的实现将不被允许(边界for<'d> QueryDb<'d>
不会满意)。