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

#![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
}

最佳答案

感谢Stefan消除了最后的皱纹



这会尝试调用:

  • 特质相关函数
  • 为特定类型实现的

  • 语法为<Type as Trait>::associated_function()。在这种情况下,TypeT1TraitGet_Static<A>,因此应为:
    <T2 as Get_Static<A>>::has_trait()
    



    无法直接表明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

    10-04 14:29