简体   繁体   English

用动态和静态调度实现特征实现者的功能

[英]Implement function for trait implementor with dynamic and static dispatch

I want to have a function foo taking an instance of a type which implements a trait A . 我想要一个函数foo获取一个实现特征A的类型的实例。 I always prefer to use generics in order to have static dispatch: 我总是喜欢使用泛型来进行静态调度:

trait A {}

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

However, this approach introduces some inflexibility, I can't pass a trait object like here: 但是,这种方法引入了一些不灵活性,我无法传递像这里的特征对象:

trait A {}

fn foo(t: &A) {}

The thing is, sometimes I know the type and sometimes not. 问题是,有时我知道类型,有时不知道。 Is there a way to have both dynamic dispatch for trait objects and static dispatch for compile time known types while not implementing things twice? 有没有办法既可以为特征对象提供动态调度,也可以为编译时已知类型提供静态调度,而不实现两次?

That is indeed possible. 这确实是可能的。 One option is to explicitly implement A for its reference types: 一种选择是为其引用类型显式实现A

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

The argument becomes a trait object when T = &A , while still doing static dispatch for known implementors of A . T = &A ,参数变为特征对象,而对A已知实现者仍然进行静态分派。 The following code should now compile: 现在应该编译以下代码:

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

struct MyA;
impl A for MyA {}

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

If you are willing to always pass a borrowed argument, you can also do this instead: 如果你愿意总是传递借来的论点,你也可以这样做:

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

The argument becomes a trait object when T = A . T = A时,该参数成为特征对象。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM