在为引用和非引用类型实现一个特性时,我是否必须实现它两次?

dav*_*ang 6 traits rust

我想为引用和非引用类型实现一个特征。我是否必须两次实现这些功能,或者这样做不是惯用的?

这是演示代码:

struct Bar {}

trait Foo {
    fn hi(&self);
}

impl<'a> Foo for &'a Bar {
    fn hi(&self) {
        print!("hi")
    }
}

impl Foo for Bar {
    fn hi(&self) {
        print!("hi")
    }
}

fn main() {
    let bar = Bar {};
    (&bar).hi();
    &bar.hi();
}
Run Code Online (Sandbox Code Playgroud)

hel*_*low 9

这是Borrowtrait 的一个很好的例子。

use std::borrow::Borrow;

struct Bar;

trait Foo {
    fn hi(&self);
}

impl<B: Borrow<Bar>> Foo for B {
    fn hi(&self) {
        print!("hi")
    }
}

fn main() {
    let bar = Bar;
    (&bar).hi();
    &bar.hi();
}
Run Code Online (Sandbox Code Playgroud)

  • 这不适用于 `Into`/`TryInto`/`From`/`TryFrom`。有解决方法吗? (3认同)

She*_*ter 8

不,您不必重复代码。相反,您可以委托:

impl Foo for &'_ Bar {
    fn hi(&self) {
        (**self).hi()
    }
}
Run Code Online (Sandbox Code Playgroud)

我会更进一步,为所有实现该特征的类型的引用实现该特征:

impl<T: Foo> Foo for &'_ T {
    fn hi(&self) {
        (**self).hi()
    }
}
Run Code Online (Sandbox Code Playgroud)

也可以看看:


&bar.hi();
Run Code Online (Sandbox Code Playgroud)

这段代码相当于&(bar.hi())但可能不是您想要的。

也可以看看: