更高级别的特质约束和函数参数

4
我正在尝试理解Bevy的IntoForEachSystem trait的实现以及它与底层Hecs QueryFetch traits的交互方式。Hecs具有查询类型(在调用query::<T>时请求的内容)和项类型(查询返回的内容)。思路是,对于其查询类型匹配查询项类型的闭包,将实现IntoForEachSystem,并且fn f(&i32)之所以有效,是因为一个&i32查询返回一个&i32项。

我认为我在这个代码片段中提取了相关的设计部分,但我无法使其通过类型检查:

// 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使用的技巧来实现相同的效果。
1个回答

1
您实际上非常接近!
fn main() {
    hmm.system();
}

这非常令人沮丧,因为我认为IntoForEachSystem :: system(hmm)应该等同于hmm.system()。也许这是Rust编译器的一个错误?

好奇怪啊。实际上这就是 Bevy 中真正的代码所做的事情。我只是改成了 UFCS 的形式,以使错误信息更清晰...... - Tim Robinson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接