更高等级的特征边界和函数参数
Higher ranked trait bounds and function parameters
我正在尝试了解 Bevy IntoForEachSystem
trait and the way it interacts with the underlying Hecs Query
and Fetch
traits 的实现。 Hecs 有查询类型(你在调用 query::<T>
时请求的东西)和项目类型(查询返回的东西)。这个想法是 IntoForEachSystem
是为查询类型与查询项类型匹配的闭包实现的,而 fn f(&i32)
之所以有效是因为 &i32
查询 returns 一个 &i32
项。
我想我在this snippet中提取了设计的相关部分,但我无法对其进行类型检查:
// Hecs Query trait
trait Query {
type Fetch: for<'a> Fetch<'a>;
}
// Hecs Query trait implementation for read-only references
impl<'a, T> Query for &'a T
where
T: 'static,
{
type Fetch = FetchRead<T>;
}
// Hecs Fetch trait
trait Fetch<'a>: Sized {
type Item;
}
// Hecs Fetch trait implementation for read-only references
struct FetchRead<T>(std::marker::PhantomData<T>);
impl<'a, T> Fetch<'a> for FetchRead<T>
where
T: 'static,
{
type Item = &'a T;
}
// Bevy IntoForEachSystem trait, simplified
trait IntoForEachSystem<R> {
fn system(self);
}
// Bevy IntoForEachSystem trait implementation for functions of one argument
impl<F, R> IntoForEachSystem<R> for F
where
F: Fn(R),
F: Fn(<<R as Query>::Fetch as Fetch>::Item),
R: Query,
{
fn system(self) {
println!("hello");
}
}
fn hmm(_x: &i32) {
todo!()
}
fn main() {
IntoForEachSystem::system(hmm)
}
错误:
error[E0631]: type mismatch in function arguments
|
31 | fn system(self);
| ---------------- required by `IntoForEachSystem::system`
...
46 | fn hmm(_x: &i32) {
| ---------------- found signature of `for<'r> fn(&'r i32) -> _`
...
51 | IntoForEachSystem::system(hmm)
| ^^^ expected signature of `for<'r> fn(<FetchRead<i32> as Fetch<'r>>::Item) -> _`
|
= note: required because of the requirements on the impl of `IntoForEachSystem<&i32>` for `for<'r> fn(&'r i32) {hmm}`
我认为编译器认为 fn hmm<'r>(&'r i32)
中的推断生命周期 'r
与 type Fetch: for<'a> Fetch<'a>
中的 forall 生命周期 'a
不同。我看不出 Bevy 用来实现同样目的的技巧。
你真的超级亲近!
fn main() {
hmm.system();
}
这……非常令人沮丧,因为就我而言,IntoForEachSystem::system(hmm)
应该等同于 hmm.system()
。也许这是 Rust 编译器中的错误?
我正在尝试了解 Bevy IntoForEachSystem
trait and the way it interacts with the underlying Hecs Query
and Fetch
traits 的实现。 Hecs 有查询类型(你在调用 query::<T>
时请求的东西)和项目类型(查询返回的东西)。这个想法是 IntoForEachSystem
是为查询类型与查询项类型匹配的闭包实现的,而 fn f(&i32)
之所以有效是因为 &i32
查询 returns 一个 &i32
项。
我想我在this snippet中提取了设计的相关部分,但我无法对其进行类型检查:
// Hecs Query trait
trait Query {
type Fetch: for<'a> Fetch<'a>;
}
// Hecs Query trait implementation for read-only references
impl<'a, T> Query for &'a T
where
T: 'static,
{
type Fetch = FetchRead<T>;
}
// Hecs Fetch trait
trait Fetch<'a>: Sized {
type Item;
}
// Hecs Fetch trait implementation for read-only references
struct FetchRead<T>(std::marker::PhantomData<T>);
impl<'a, T> Fetch<'a> for FetchRead<T>
where
T: 'static,
{
type Item = &'a T;
}
// Bevy IntoForEachSystem trait, simplified
trait IntoForEachSystem<R> {
fn system(self);
}
// Bevy IntoForEachSystem trait implementation for functions of one argument
impl<F, R> IntoForEachSystem<R> for F
where
F: Fn(R),
F: Fn(<<R as Query>::Fetch as Fetch>::Item),
R: Query,
{
fn system(self) {
println!("hello");
}
}
fn hmm(_x: &i32) {
todo!()
}
fn main() {
IntoForEachSystem::system(hmm)
}
错误:
error[E0631]: type mismatch in function arguments
|
31 | fn system(self);
| ---------------- required by `IntoForEachSystem::system`
...
46 | fn hmm(_x: &i32) {
| ---------------- found signature of `for<'r> fn(&'r i32) -> _`
...
51 | IntoForEachSystem::system(hmm)
| ^^^ expected signature of `for<'r> fn(<FetchRead<i32> as Fetch<'r>>::Item) -> _`
|
= note: required because of the requirements on the impl of `IntoForEachSystem<&i32>` for `for<'r> fn(&'r i32) {hmm}`
我认为编译器认为 fn hmm<'r>(&'r i32)
中的推断生命周期 'r
与 type Fetch: for<'a> Fetch<'a>
中的 forall 生命周期 'a
不同。我看不出 Bevy 用来实现同样目的的技巧。
你真的超级亲近!
fn main() {
hmm.system();
}
这……非常令人沮丧,因为就我而言,IntoForEachSystem::system(hmm)
应该等同于 hmm.system()
。也许这是 Rust 编译器中的错误?