簡體   English   中英

為什么我的Trait實現不匹配?

[英]Why does my Trait implementation not match?

如何使此代碼編譯?

trait Pair<'a, A, B> {
    fn first_ref(&'a self) -> &'a A;
    fn second_ref(&'a self) -> &'a B;
};

struct PairOwned<A, B> {
    first: A,
    second: B,
}

// Only implemented for the cases we are interested in ...
impl<'a, A, B> Pair<'a, A, B> for &'a PairOwned<&'a A,&'a B> {
    fn first_ref(&'a self) -> &'a A {
        self.first
    }
    fn second_ref(&'a self) -> &'a B {
        self.second
    }
}

impl<'a, A, B> Pair<'a, A, B> for &'a(&'a A, &'a B) {
    fn first_ref(&'a self) -> &'a A {
        self.0
    }
    fn second_ref(&'a self) -> &'a B {
        self.1
    }
}

fn pair_transformer<'a, I, T>(pairs: I) -> String
    where   T: Pair<'a, &'a Str, &'a Str> + 'a,
            I: Iterator<Item=T> {
    let mut s = String::new();
    for pair in pairs {
        s = s
            + pair.first_ref().as_slice()
            + pair.second_ref().as_slice();
    }
    s
}

pair_transformer([PairOwned { first: "a", second: "b" }].iter());
pair_transformer([("a", "b")].iter());

編譯器說:

tests/lang.rs:902:5: 902:21 error: the trait `pair_trait_for_iteration::Pair<'_, &core::str::Str, &core::str::Str>` is not implemented for the type `&pair_trait_for_iteration::PairOwned<&str, &str>` [E0277]
 tests/lang.rs:902     pair_transformer([PairOwned { first: "a", second: "b" }].iter());
                      ^~~~~~~~~~~~~~~~
tests/lang.rs:903:5: 903:21 error: the trait `pair_trait_for_iteration::Pair<'_, &core::str::Str, &core::str::Str>` is not implemented for the type `&(&str, &str)` [E0277]
tests/lang.rs:903     pair_transformer([("a", "b")].iter());

筆記

我覺得這與指定應針對某個特性實施的各種方式有某種聯系,而我對此尚未完全理解。

// As stated in the answer at 
// http://stackoverflow.com/questions/28283641/what-is-the-preferred-way-to-implement-the-add-trait-efficiently-for-vector-type
impl Add<YourType> for YourType { ... }
impl<'r> Add<YourType> for &'r YourType { ... }
impl<'a> Add<&'a YourType> for YourType { ... }
impl<'r, 'a> Add<&'a YourType> for &'r YourType { ... }

rustc 1.0.0-nightly (522d09dfe 2015-02-19) (built 2015-02-19)使用rustc 1.0.0-nightly (522d09dfe 2015-02-19) (built 2015-02-19)

您的代碼中有幾個錯誤:

  • 您可能想直接為您的類型實現特征,因為特征定義的方法通過引用來獲取特征(在鏈接的其他帖子中不是“ Add特征”的情況)
  • 您實際上並未擁有對OwnedPair { first: "a", second: "b"}使用權OwnedPair { first: "a", second: "b"} :您的類型將為OwnedPair<&'static str, &'static str>因此我在String包含了示例(已擁有)我以為那就是你想要的
  • 迭代器返回的項實際上是引用,因此您可能希望將I綁定到Iterator<Item=&'a T>

當我嘗試盡可能通用時(例如,使用OwnedPair<&str,&str>OwnedPair<String,String>進行編譯的示例),我使用了特性std :: OwnedPair<String,String> :: Borrow,這基本上意味着它是可以從實現此特征的類型中借用對類型T的引用。

我還需要使用?Sized作為大多數類型參數的綁定。 這允許使用大小在編譯時未知的類型,並將在“胖指針”后面使用。 此博客文章中的更多信息(有點舊)

這是完整的更正代碼(可在playpen中運行)

use std::borrow::Borrow;

trait Pair<'a, A: ?Sized, B: ?Sized> {
    fn first_ref(&'a self) -> &'a A;
    fn second_ref(&'a self) -> &'a B;
}

struct PairOwned<A, B> {
    first: A,
    second: B,
}

// Only implemented for the cases we are interested in ...
impl<'a, ARef: ?Sized, BRef: ?Sized, A: Borrow<ARef>, B: Borrow<BRef>> Pair<'a, ARef, BRef> for PairOwned<A,B> {
    fn first_ref(&'a self) -> &'a ARef {
        self.first.borrow()
    }
    fn second_ref(&'a self) -> &'a BRef {
        self.second.borrow()
    }
}

// It should also be possible to be more generic here with Borrow
// But I wanted to leave your original implementation
impl<'a, A: ?Sized, B: ?Sized> Pair<'a, A, B> for (&'a A, &'a B) {
    fn first_ref(&'a self) -> &'a A {
        self.0
    }
    fn second_ref(&'a self) -> &'a B {
        self.1
    }
}

fn pair_transformer<'a, I, T>(pairs: I) -> String
    where   T: Pair<'a, str, str> + 'a,
            I: Iterator<Item=&'a T> {
    let mut s = String::new();
    for pair in pairs {
        s = s
            + pair.first_ref().as_slice()
            + pair.second_ref().as_slice();
    }
    s
}

fn main() {
    pair_transformer([PairOwned { first: "a".to_string(), second: "b".to_string() }].iter());
    pair_transformer([PairOwned { first: "a".to_string(), second: "b" }].iter()); // It is even possible to mix String and &str
    pair_transformer([PairOwned { first: "a", second: "b" }].iter());
    pair_transformer([("a", "b")].iter());
}

暫無
暫無

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

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