【问题标题】:Get string as a value in formatted output获取字符串作为格式化输出中的值
【发布时间】:2016-05-12 10:12:27
【问题描述】:

我正在尝试通过Rust by Example website 上的“元组课程”,但我被格式化的输出实现所困。我有这段代码,它打印传递的矩阵:

#[derive(Debug)]
struct Matrix{
  data: Vec<Vec<f64>>   // [[...], [...],] 
}

impl fmt::Display for Matrix {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let output_data = self.data
            // [[1, 2], [2, 3]] -> ["1, 2", "2, 3"]
            .into_iter()
            .map(|row| {
                row.into_iter()
                    .map(|value| value.to_string())
                    .collect::<Vec<String>>()
                    .join(", ")
            })
            .collect::<Vec<String>>()
            // ["1, 2", "2, 3"] -> ["(1, 2)", "(2, 3)"]
            .into_iter()
            .map(|string_row| { format!("({})", string_row) })
            // ["(1, 2)", "(2, 3)"] -> "(1, 2),\n(2, 3)"
            .collect::<Vec<String>>()
            .join(",\n");
        write!(f, "{}", output_data)
    }
}

但是编译器会打印下一条消息:

<anon>:21:40: 21:44 error: cannot move out of borrowed content [E0507]
<anon>:21         let output_data = self.data
                                    ^~~~
<anon>:21:40: 21:44 help: see the detailed explanation for E0507
error: aborting due to previous error
playpen: application terminated with error code 101

我尝试将output_data 的结果包装成RefCell,但编译器仍会打印此错误。如何解决此问题,以使 write! 宏正常工作?

【问题讨论】:

    标签: string pointers rust borrowing


    【解决方案1】:

    问题是into_inter 拥有data 的所有权,即从self 移出data,这是不允许的(这就是错误所说的)。要在不获取所有权的情况下迭代向量,请使用iter 方法:

    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let output_data = self.data
            // [[1, 2], [2, 3]] -> ["1, 2", "2, 3"]
            .iter()
            .map(|row| {
                row.into_iter()
                    .map(|value| value.to_string())
                    .collect::<Vec<String>>()
                    .join(", ")
            })
            .collect::<Vec<String>>()
            // ["1, 2", "2, 3"] -> ["(1, 2)", "(2, 3)"]
            .into_iter()
            .map(|string_row| { format!("({})", string_row) })
            // ["(1, 2)", "(2, 3)"] -> "(1, 2),\n(2, 3)"
            .collect::<Vec<String>>()
            .join(",\n");
        write!(f, "{}", output_data)
    }
    

    看看Formatter。它有一些方法可以帮助编写fmt。这是一个不分配中介向量和字符串的版本:

    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let mut sep = "";
        for line in &self.data { // this is like: for line in self.data.iter()
            try!(f.write_str(sep));
            let mut d = f.debug_tuple("");
            for row in line {
                d.field(row);
            }
            try!(d.finish());
            sep = ",\n";
        }
        Ok(())
    }
    

    【讨论】:

      猜你喜欢
      • 2014-11-06
      • 1970-01-01
      • 2010-10-20
      • 2012-03-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-28
      • 1970-01-01
      相关资源
      最近更新 更多