2017-01-23 60 views
5

我想要一个功能foo,该功能采用实现特征A的类型的实例。我总是喜欢以使用泛型具有静态调度:使用动态和静态调度来实现特征实现者的功能

trait A {} 

fn foo<T: A>(t: T) {} 

然而,这种方法引入了一些灵活性,我无法通过一个特质对象喜欢这里:

trait A {} 

fn foo(t: &A) {} 

的事情是,有时我知道类型,有时不知道。有没有一种方法可以为编译时间已知类型同时拥有对特征对象的动态分派和静态分派,同时又不会执行两次?

回答

6

这确实是可能的。一种选择是明确的实施A其引用类型:

impl<'a, T: A + ?Sized> A for &'a T {} 

的争论变成特质对象时T = &A,同时还在做静态调度为A知实现者。下面的代码现在应该编译:

fn foo<T: A>(a: T) {} 

struct MyA; 
impl A for MyA {} 

fn main() { 
    foo(MyA{}); 
    foo(&MyA{}); 
    foo(&MyA{} as &A); 
} 

如果你愿意总是传递借来的说法,你也可以做到这一点,而不是:

fn foo<T: A + ?Sized>(a: &T) {} 

的争论成为一个特质对象T = A时。

+0

我不确定我是否完全理解你的'fn foo'。 'Sized'上总是没有隐含的限制吗? – torkleyy

+1

@torkleyy在函数参数上,是的。这是可以的,因为我们提供的是无论如何确实总是大小。第二个函数使用'&T',即使T不是,也可以调整大小。 –