如何检查泛型类型是否实现了一般特征?

时间:2017-12-08 06:50:24

标签: 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
}

1 个答案:

答案 0 :(得分:1)

感谢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()。在这种情况下,TypeT1TraitGet_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