在Rust Generic性状实现中,如何避免“ T1”类型“ T1”是不受限制的。当我只需要T1的TypeID时?

发布于 2025-01-25 18:47:47 字数 2466 浏览 4 评论 0 原文

我正在学习生锈并通过 typeid 进行实验。我正在寻找是否有可能在依赖性注入中制作一个简单的IOC容器,但是我遇到了一个函数的通用性状实现问题:

use std::any::{Any, TypeId};

trait IocInjectable<T> {
   fn get_injectables_list(&self) -> Vec<TypeId>;
   
   fn inject(&mut self, injectables: Vec<&dyn Any>) -> T;
}

impl<Func, T1, T2, TRet> IocInjectable<TRet> for Func
where
    Func: Fn(&T1, &T2) -> TRet + 'static,
    T1: 'static, // not sure, what goes here?
    T2: 'static
{
    fn get_injectables_list(&self) -> Vec<TypeId> {
        return vec![TypeId::of::<T1>(), TypeId::of::<T2>()];
    }

    fn inject(&mut self, injectables: Vec<&dyn Any>) -> TRet {
        let arg1 = injectables[0].downcast_ref::<T1>().unwrap(); 
        let arg2 = injectables[1].downcast_ref::<T2>().unwrap();
        return self(arg1, arg2);
    }
}

我遇到了一个错误:

error[E0207]: the type parameter `T1` is not constrained by the impl trait, self type, or predicates
 --> src/lib.rs:9:12
  |
9 | impl<Func, T1, T2, TRet> IocInjectable<TRet> for Func
  |            ^^ unconstrained type parameter

“ nofollow noreferrer

”一般的功能?

更新在查看链接问题的答案后,我能够解决编译器错误。请注意,这不是最佳/最终/良好解决方案,这只是解决编译器错误。

use std::any::{Any, TypeId};

trait IocInjectable<TArgs> {

    type TRet;

    fn get_injectables_list(&self) -> Vec<TypeId>;

    fn inject(&mut self, injectables: Vec<&dyn Any>) -> Self::TRet;
}

impl<Func, T1, T2, TRet1> IocInjectable<(T1, T2)> for Func
where
    Func: Fn(&T1, &T2) -> TRet1 + 'static,
    T1: 'static,
    T2: 'static
{
    type TRet = TRet1;

    fn get_injectables_list(&self) -> Vec<TypeId> {
        return vec![TypeId::of::<T1>(), TypeId::of::<T2>()];
    }

    fn inject(&mut self, injectables: Vec<&dyn Any>) -> TRet1 {
        let arg1 = injectables[0].downcast_ref::<T1>().unwrap(); 
        let arg2 = injectables[1].downcast_ref::<T2>().unwrap();
        return self(arg1, arg2);
    }
}

I'm learning Rust and experimenting with TypeId. I'm looking to see if it is possible to make a simplistic IoC container with it for Dependency Injection, but I've hit a problem with generic trait implementation for a function:

use std::any::{Any, TypeId};

trait IocInjectable<T> {
   fn get_injectables_list(&self) -> Vec<TypeId>;
   
   fn inject(&mut self, injectables: Vec<&dyn Any>) -> T;
}

impl<Func, T1, T2, TRet> IocInjectable<TRet> for Func
where
    Func: Fn(&T1, &T2) -> TRet + 'static,
    T1: 'static, // not sure, what goes here?
    T2: 'static
{
    fn get_injectables_list(&self) -> Vec<TypeId> {
        return vec![TypeId::of::<T1>(), TypeId::of::<T2>()];
    }

    fn inject(&mut self, injectables: Vec<&dyn Any>) -> TRet {
        let arg1 = injectables[0].downcast_ref::<T1>().unwrap(); 
        let arg2 = injectables[1].downcast_ref::<T2>().unwrap();
        return self(arg1, arg2);
    }
}

I'm getting an error:

error[E0207]: the type parameter `T1` is not constrained by the impl trait, self type, or predicates
 --> src/lib.rs:9:12
  |
9 | impl<Func, T1, T2, TRet> IocInjectable<TRet> for Func
  |            ^^ unconstrained type parameter

Rust playground

Is there any way to make this approach with a function generically?

Update After reviewing answers for linked questions, I was able to solve compiler errors. Mind you, this is not optimal/final/good solution, this just solves the compiler error.

use std::any::{Any, TypeId};

trait IocInjectable<TArgs> {

    type TRet;

    fn get_injectables_list(&self) -> Vec<TypeId>;

    fn inject(&mut self, injectables: Vec<&dyn Any>) -> Self::TRet;
}

impl<Func, T1, T2, TRet1> IocInjectable<(T1, T2)> for Func
where
    Func: Fn(&T1, &T2) -> TRet1 + 'static,
    T1: 'static,
    T2: 'static
{
    type TRet = TRet1;

    fn get_injectables_list(&self) -> Vec<TypeId> {
        return vec![TypeId::of::<T1>(), TypeId::of::<T2>()];
    }

    fn inject(&mut self, injectables: Vec<&dyn Any>) -> TRet1 {
        let arg1 = injectables[0].downcast_ref::<T1>().unwrap(); 
        let arg2 = injectables[1].downcast_ref::<T2>().unwrap();
        return self(arg1, arg2);
    }
}

Rust playground

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文