rust - 如何检查泛型类型是否实现了泛型特征?

标签 rust template-specialization

我想在不创建对象的情况下检查类型是否实现了特征。但它不编译。请参阅代码中的注释。那么我应该怎么做才能实现我的目标?

#![feature(specialization)]

struct T1;
struct T2;

trait A {}

impl A for T1 {}

trait Get_Static<TraitType> {
    fn has_trait() -> bool ;
}
default impl<TraitType, T> Get_Static<TraitType> for T
{
    fn has_trait() -> bool { false }
}
impl<TraitType, T> Get_Static<TraitType> for T where T:TraitType
{
    fn has_trait() -> bool { true }
}//Compiler complains TraitType is not a trait but type parameter

fn main() {
    if <T1 as Get_Static>::<A>::has_trait() {println!("{}", true)} else {println!("{}", false)}
    if <T2 as Get_Static>::<A>::has_trait() {println!("{}", true)} else {println!("{}", false)}
//This is surely wrong syntax but I don't know the right syntax
}

最佳答案

警告:此解决方案不再适用于最近的 nightly (2022-01),并且不知道何时停止工作。


感谢 Stefan 抚平了最后的皱纹。

<T2 as Get_Static>::<A>::has_trait()
  //This is surely wrong syntax but I don't know the right syntax

这会尝试调用:

  • 特征相关函数,
  • 针对特定类型实现。

语法是<Type as Trait>::associated_function() .在这种情况下,TypeT1 , TraitGet_Static<A>所以这应该是:

<T2 as Get_Static<A>>::has_trait()
impl<TraitType, T> Get_Static<TraitType> for T where T:TraitType
{
    fn has_trait() -> bool { true }
}
//Compiler complains TraitType is not a trait but type parameter

不可能直接表明TraitType应该是 trait , 然而 Unsize 标记可用于检查是否 T: Unsize<TraitType>这足以满足我们的目的。

这需要 3 个更改:

  • 启用夜间功能 #![feature(unsize)]作为 Unsize标记不稳定,
  • 允许Get_Static通用参数为 ?Sized ,因为特征未定大小,
  • 使用T: Unsize<TraitType>作为实现中的约束。

总而言之,这意味着:

#![feature(specialization)]
#![feature(unsize)]

trait GetStatic<TraitType: ?Sized> {
    fn has_trait() -> bool ;
}

default impl<TraitType: ?Sized, T> GetStatic<TraitType> for T {
    fn has_trait() -> bool { false }
}

impl<TraitType: ?Sized, T> GetStatic<TraitType> for T 
    where
        T: std::marker::Unsize<TraitType>
{
    fn has_trait() -> bool { true }
}

然后用作:

struct T1;
struct T2;

trait A {}

impl A for T1 {}

fn main() {
    println!("{}", <T1 as GetStatic<A>>::has_trait());
    println!("{}", <T2 as GetStatic<A>>::has_trait());
}

See it in action on the playground

关于rust - 如何检查泛型类型是否实现了泛型特征?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47709129/

相关文章:

rust - 我可以创建一个自定义迭代器迭代一个序列然后另一个(链不起作用)

rust - 为什么不安全的代码可以编译,但推送到向量的类似代码会提示引用的生命周期不够长?

c++ - 在命名空间 std 之外专门化 std::hash 是否不安全?

c++ - 根据可散列的模板使用正确的容器类型

c++ - 为什么不能重载类模板?

rust - 如何为关联类型实现From?

multithreading - 如何在线程之间共享非发送对象?

rust - 如何在过程宏中提供有用的编译器错误?

c++ - 特化 std::optional

c++ - 使用另一个模板类的嵌套名称说明符专门化一个模板类