簡體   English   中英

在為引用和非引用類型實現一個特性時,我是否必須實現它兩次?

[英]Do I have to implement a trait twice when implementing it for both reference and non-reference types?

我想為引用和非引用類型實現一個特征。 我是否必須兩次實現這些功能,或者這樣做不是慣用的?

這是演示代碼:

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();
}

這是Borrow特性的一個很好的例子。

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();
}

不,您不必復制代碼。 相反,您可以委托:

impl Foo for &'_ Bar {
    fn hi(&self) {
        (**self).hi()
    }
}

我會更進一步,為所有對實現該特性的類型的引用實現該特性:

impl<T: Foo> Foo for &'_ T {
    fn hi(&self) {
        (**self).hi()
    }
}

也可以看看:


&bar.hi();

此代碼等效於&(bar.hi())並且可能不是您想要的。

也可以看看:

您可以使用Cow

use std::borrow::Cow;

#[derive(Clone)]
struct Bar;

trait Foo {
    fn hi(self) -> &'static str;
}

impl<'a, B> Foo for B where B: Into<Cow<'a, Bar>> {
    fn hi(self) -> &'static str {
        let bar = self.into();

        // bar is either owned or borrowed:
        match bar {
            Cow::Owned(_) => "Owned",
            Cow::Borrowed(_) => "Borrowed",
        }
    }
}

/* Into<Cow> implementation */

impl<'a> From<Bar> for Cow<'a, Bar> {
    fn from(f: Bar) -> Cow<'a, Bar> {
        Cow::Owned(f)
    }
}

impl<'a> From<&'a Bar> for Cow<'a, Bar> {
    fn from(f: &'a Bar) -> Cow<'a, Bar> {
        Cow::Borrowed(f)
    }
}

/* Proof it works: */

fn main() {
    let bar = &Bar;
    assert_eq!(bar.hi(), "Borrowed");

    let bar = Bar;
    assert_eq!(bar.hi(), "Owned");
}

Borrow相比的一個優勢是,您知道數據是通過值還是引用傳遞,如果這對您很重要。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM