2017-12-27 40 views
0

반복자에서 데이터의 서식을 지정하는 방법을 만들고 있습니다. 허용하려면 체인, 내가 제네릭을 통해 반복자의 새로운 방법으로 제공하기 위해 노력하고있어 : 다음모든 반복자에 대한 특성 구현

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::MapIterator<Item = T> + Clone을 구현하므로 문제가 어디에 있습니까?

도움을 주셔서 감사합니다.

+0

같은 to_separated_string를 다시 작성하여 Clone에 대한 요구 사항을 제거 할 수 있습니다. co.kr/help/mcve)를 사용하면 더 나은 답변을 얻을 수 있습니다. – red75prime

+0

나는 몰랐다. 나는 미래의 질문을 염두에 두겠다. – Nanocryk

답변

1

MCVE 귀하의 질문에 대한

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

다음과 같은 가정에서 잘못을 같이 쓸 수

std::iter::Map 녹 설명서 std::iter::Map에 대한 Iterator<Item = T> + Clone

Trait implementations 섹션 포함을 구현

소스 및 반복자 I 함수 F 유형 모두를 구현할 때 Clone Map이다 1,515,
impl<I, F> Clone for Map<I, F> where 
    F: Clone, 
    I: Clone, 

Clone을 구현한다.

클로저는 현재 stable Rust 버전 1.22.1에 Clone을 구현하지 않습니다. 이 기능은 기능 게이트 clone_closures 아래 야간 녹에서 사용할 수 있습니다. // 유래 : Playground link

또한 [, 최소를 완료하고 검증 가능한 예 (MCVE)] (HTTPS를 게시하는

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 
} 

Playground link

+0

좋은 답변입니다. [copy/clone closures RFC] (https://github.com/rust-lang/rfcs/blob/master/text/2132-copy-closures.md) –

+0

에 대한 참조 추가 클로저에 대해 생각하지 않았습니다. . 이 튜플 설정 중 하나가 아니더라도 작업 코드를 보내 주셔서 감사합니다. 매우 우아하고 나중에 이런 종류의 것을 사용하려고 노력할 것입니다. 너는 그 종류의 속임수를 발견 할 수있는 장소를 안다? – Nanocryk