【发布时间】:2023-04-10 02:05:01
【问题描述】:
我有以下锈sn-p:
trait Foo {
fn foo(&self);
}
struct FooImpl;
impl Foo for FooImpl {
fn foo(&self) {}
}
fn do_foo(foo_doer: impl Foo) {
foo_doer.foo()
}
这条线有效:
do_foo(FooImpl {});
但是当我尝试运行它时:
do_foo(&FooImpl {});
我得到错误是可以理解的:the trait bound &FooImpl: Foo is not satisfied。
我显然可以这样做:
impl Foo for &FooImpl { fn foo(&self) {} }
然后它会起作用,但是我必须为多种类型执行此操作,并且每次都必须复制一些代码。此外,在我的情况下,我不仅可以获得借用,还可以获得可变借用。这意味着我必须为&mut FooImpl 实现它,有时我想从可变借用的不可变借用中运行它,这意味着我必须为&&mut FooImpl 实现它,你明白了。
我的问题是,您是否可以推荐一些 trait impl / generic 技巧,让我可以为拥有的实例和借用的实例实现 trait?
或者,我可以在 do_foo 函数方面进行更改,使其能够接受这两种类型的实例吗?
我已阅读 Do I have to implement a trait twice when implementing it for both reference and non-reference types?,它适用于我的玩具程序。但我的问题是我试图在我的实际代码中实现的特征来自不同的板条箱,所以编译器不允许我在我认为由于孤儿规则的那个特征上实现 Borrow<FooImpl>(错误:type parameter B must be used as the type parameter for some local type) .是否有解决孤儿规则的解决方案?
【问题讨论】:
-
定义一个宏并用它来生成你的实现?
-
在这里应用 Shepmaster 对另一个问题的回答:
impl<F: ?Sized> Foo for &'_ F where F: Foo {...}将涵盖您关于&引用的所有基础,如果您愿意,您可以对&mut引用执行相同操作。?Sized绑定不是绝对必要的,但允许您使用引用实现来引用 trait 对象。 -
另请阅读When should I not implement a trait for references to implementors of that trait?,它解释了为什么需要额外的
impls。 -
@trentcl 谢谢,但我的特点是在不同的箱子里,忘了提,看我的编辑。第二个链接也很有启发性,因此也非常感谢。
-
如果它在不同的 crate 中,要么 crate 本身应该提供这个
impl,要么有一些关于FooImpl的特殊之处使得对它的引用特别,因为它们可以实现Foo虽然一般来说,不能引用实现Foo的其他类型。我知道没有一般的解决方法(除了使用宏,如eggyal建议的那样)帽子,但可能有一个适合您的具体情况;不幸的是,该问题没有包含足够的信息来提出建议。
标签: generics rust traits ownership borrowing