generics - 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。
解决方案
有一种通用的方法可以在稳定的 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
}
推荐阅读
- confluent-platform - 无法在 Arcadia BI 工具中加载 KSQL 表
- flutter - 如何从方法中返回两个值
- r - 在 R 中合并具有许多不匹配列的多个大型数据框
- excel - 修改文件信息的VBA飞跃1小时
- julia - 如何访问 Julia 的 CuArray 中的元素并更改其值?
- android-studio - Android Studio 3.6.3 更新不会在单击“运行”图标时启动 apk
- javascript - Promise 中的多个 resolve() 调用返回异步函数
- reactjs - 如何以编程方式在自定义反应组件中添加 parsys?
- c++ - 如何在模板实例化中强制将 char[] 转换为 char*?
- java - 将 Spring Cloud 配置服务器连接到本地 git repo 失败