首页 > 解决方案 > Rust:有没有办法知道一个 arg 是某种泛型类型,而不关心它的内部类型?

问题描述

我知道我可以使用TypeId来确定 arg 是否属于某种特定类型:

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

fn is_string<T: ?Sized + Any>(_s: &T) -> bool {
    TypeId::of::<String>() == TypeId::of::<T>()
}

但是有没有办法知道 arg 是某种泛型类型,而不关心内部类型?

例如,我可以在不关心内部类型的情况下以某种方式找出 arg 是否是 Vec<_>?

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

fn is_vec<T: ?Sized + Any>(_s: &T) -> bool {
    TypeId::of::<Vec<_>>() == TypeId::of::<T>() // This fails with error[E0282]: type annotations needed
}

我想知道这是否可以在 Rust 中以任何方式实现,而不仅仅是使用 TypeId。

标签: genericsrust

解决方案


有一种通用的方法可以在稳定的 rust 中执行此操作,尽管它不会让您检查 adyn Any是否为 a Vec<_>。相反,我所做的是为 any 创建一个超级特征,并为Vec<T>dyn Any. 代码:

trait MyAny:Any{
    fn get_container(&self)->Container;
} 

impl<T:Any> MyAny for Vec<T>{
    fn get_container(&self)->Container{
        Vector
    }
}
impl MyAny for dyn Any{
    fn get_container(&self)->Container{
        Any
    }
}

容器是一个定义为的枚举

#[derive(Clone,Copy,PartialEq,Eq)]
#[non_exhaustive]
enum Container{
    Vector,
    Any,
}

从那里开始,定义一个is_vec函数很容易:

fn is_vec<T:MyAny + ?Sized>(s:&T)->bool{
    s.get_container() == Vector
}

操场


推荐阅读