rust - 更高等级的特征边界和函数参数

标签 rust higher-rank-types bevy

我试图了解 Bevy 的实现 IntoForEachSystem trait以及它与底层 Hec 交互的方式 Query and Fetch traits . Hecs 具有查询类型(您在调用 query::<T> 时请求的内容)和项目类型(查询返回的内容)。这个想法是IntoForEachSystem为查询类型与查询的项目类型匹配的闭包实现,并且 fn f(&i32)工作是因为 &i32查询返回 &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}`
我认为编译器正在看到推断的生命周期 'rfn hmm<'r>(&'r i32)与永久生命周期不同 'atype Fetch: for<'a> Fetch<'a> .我没有看到 Bevy 用来实现同样目标的技巧。

最佳答案

你真的 super 接近!

fn main() {
    hmm.system();
}
这是...非常令人沮丧,因为IntoForEachSystem::system(hmm)应该等同于 hmm.system()就我而言。也许这是 Rust 编译器中的一个错误?

关于rust - 更高等级的特征边界和函数参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63862052/

相关文章:

rust - 当我添加生命周期时,有没有办法避免向所有下游结构添加生命周期?

rust - 我可以在循环的多次迭代中传递相同的可变特征对象而不添加间接寻址吗?

rust - Rust 中具有不断变化的行为的有限(游戏)状态机模式?

haskell - ST 周围的 newtype 导致类型错误

rust - 使用 HRTB 自动化 getter 方法单元测试

c++ - 在 C++ 中作为参数的多态(通用)函数

rust - 是否可以在不直接通过线程本地系统使用“世界”的情况下将一个或多个子代添加到实体?

rust - 如何在 Rust 中构建多工作区 cargo 项目

rust - 如何在 bevy 中旋转和移动对象

rust - 如何向场景中产生的实体添加组件?