簡體   English   中英

實現所有迭代器的特征

[英]Implement trait for all Iterator

我正在創建一種方法來格式化迭代器中的數據。 為了允許鏈接,我試圖通過泛型將其作為Iterator的新方法提供:

trait ToSeparatedString {
    fn to_separated_string(self, line_prefix: &str, separator: &str) -> String;
}

impl<T, I> ToSeparatedString for I
where
    T: Display,
    I: Iterator<Item = T> + Clone,
{
    fn to_separated_string(self, line_prefix: &str, separator: &str) -> String {
        let len = self.clone().count();

        self.enumerate()
            .map(|(i, line)| if i < len - 1 {
                (line, separator)
            } else {
                (line, "")
            })
            .fold::<String, _>("".to_owned(), |acc, (line, line_end)| {
                format!("{}{}{}{}", acc, line_prefix, line, line_end)
            })
    }
}

然后我在這里使用它:

#[derive(Debug)]
pub struct TransactionDocumentBuilder<'a> {
    /// Currency Id.
    pub currency: &'a str,
    /// Document timestamp.
    pub blockstamp: Blockstamp,
    /// Transaction locktime (in seconds ?)
    pub locktime: u64,
    /// List of issuers.
    pub issuers: Vec<ed25519::PublicKey>,
    /// List of inputs.
    pub inputs: Vec<Input>,
    /// List of outputs.
    pub outputs: Vec<Output>,
    /// Transaction comment.
    pub comment: &'a str,
}

impl<'a> DocumentBuilder<TransactionDocument> for TransactionDocumentBuilder<'a> {
    fn build_with_signature(self, signature: ed25519::Signature) -> TransactionDocument {
        TransactionDocument {
            document: GenericDocumentBuilder::new(10, "Transaction", self.currency)
                .with("Blockstamp", &self.blockstamp.to_string())
                .with("Locktime", &self.locktime.to_string())
                .with("Issuers", &self.issuers.iter().to_separated_string("", "\n"))
                .with("Inputs", &self.inputs.iter()
                    .map(|input| input.source)
                    .to_separated_string("", " "))
                // Iterate through each input unlocks
                .with("Unlocks", &self.inputs.iter()
                    .enumerate()
                    .map(|(i, input)| {
                        input.unlocks.iter().to_separated_string(&i.to_string(), "\n")
                    })
                    .to_separated_string("", "\n")
                )
                // more fields
                .build_with_signature(signature),
        };

        unimplemented!()
    }

    fn build_and_sign(self, _private_key: &ed25519::PrivateKey) -> TransactionDocument {
        unimplemented!()
    }
}

當我在.iter()而不是.map()之后使用它時,它是有效的,並表示未實現。 但是std::slice::Iterstd::iter::Map實現了Iterator<Item = T> + Clone ,那么問題出在哪里呢?

預先感謝您的幫助。

您的問題的MCVE可以寫成

vec![1,2,3].iter().map(|x| x).to_separated_string("", "")

您在以下假設中錯了

std::iter::Map實現Iterator<Item = T> + Clone

Rust文檔中std::iter::Map Trait實現部分包括

impl<I, F> Clone for Map<I, F> where
    F: Clone,
    I: Clone, 

這是Map實現Clone當源迭代器I和函數的類型F都實現Clone

不幸的是,在當前穩定的Rust版本1.22.1中,閉包沒有實現Clone 該功能可在每晚Rust的特征門clone_closures 游樂場鏈接

您還可以通過這樣重寫to_separated_string來刪除對Clone的要求

fn to_separated_string(self, line_prefix: &str, separator: &str) -> String {
    self.fold((true, "".to_string()), |(first, acc), line| {
        (
            false,
            format!(
                "{}{}{}{}",
                acc,
                if first { "" } else { separator },
                line_prefix,
                line
            ),
        )
    }).1
}

游樂場鏈接

暫無
暫無

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

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