Зову пиши!выводит строку, завернутую в Ok () в ржавчине - PullRequest
1 голос
/ 31 мая 2019

При попытке прочитать файл и записать его в другой файл каждая строка переносится внутри Ok () при использовании write !. Мне не удалось обнаружить, что я делаю неправильно, надеюсь, у кого-нибудь появится идея.

Мне удалось выделить проблему, связанную с {: #?}.

Если я помещу регулярный текст в "", он печатается нормально и за пределами Ok (). Кто-нибудь еще сталкивался с этим?

Спасибо

use std::fs::File;
use std::io::{BufReader, BufRead};
use std::io::{Write, Error};

fn main() -> Result<(), Error> {

    let ofile = File::open("test.xml")?;
    let mut new_file = File::create("output.xml")?;
    let input = BufReader::new(ofile);

    for line in input.lines() {
        write!(new_file, "{:#?}", line)?;
    }

    Ok(())
}

Input

<?xml version = '1.0' encoding = 'UTF-8'?>
<Configuration xmlns="configuration" configType="TEST_RULE" actionType="NEW RULE">
   <Reference>
      <Code>AV</Code>
      <Name>TESTER</Name>
   </Reference>
   <ConfigItems>
      <ConfigItem>
         <description>Test Description</description>
      </ConfigItem>
   </ConfigItems>
</Configuration>

Результирующий вывод

Ok(
    "<?xml version = \'1.0\' encoding = \'UTF-8\'?>"
)Ok(
    "<Configuration xmlns=\"configuration\" configType=\"TEST_RULE\" actionType=\"NEW RULE\">"
)Ok(
    "   <Reference>"
)Ok(
    "      <Code>AV</Code>"
)Ok(
    "      <Name>TESTER</Name>"
)Ok(
    "   </Reference>"
)Ok(
    "   <ConfigItems>"
)Ok(
    "      <ConfigItem>"
)Ok(
    "         <description>Test Description</description>"
)Ok(
    "      </ConfigItem>"
)Ok(
    "   </ConfigItems>"
)Ok(
    "</Configuration>"
)

Исправлена ​​ошибка: Согласно ответу ниже, я изменил запись! к следующему, и это решило проблему.

write!(new_file, "{}\n", line?)?;

1 Ответ

0 голосов
/ 01 июня 2019

Вызов .lines() на BufReader дает вам io::Lines, чей связанный Item -тип - std::io::Result<String>. То есть при итерации по .lines() итератор выдает либо Ok(String) (в случае успешного чтения), либо Err(io::Error) (в случае возникновения ошибки io при чтении следующей строки). Вот почему вы видите, как печатается Ok(...).

Обычно можно увидеть что-то вроде следующего:

for line in input.lines() {
    // If `line` is `Ok(String)`, re-assign `line`; return the error otherwise.
    let line = line?;
    // Possible read-errors have been dealt with, `line` is a `String`.
    write!(new_file, "{:#?}", line)?;
}

В случае, если вас смущает тип чего-либо, также обычной практикой является присвоение переменной вашего ожидаемого или какого-то «абсурдного» типа, просто чтобы компилятор кричал на вас.

for line in input.lines() {
    let line: String = line; // line should be a String, right?
    let line: () = line; // I have no idea what line is, but it's not () for sure 
    write!(new_file, "{:#?}", line)?;
}

Оба let line: ... = line приведут к тому, что компилятор выдаст ошибку, потому что line равен Result<String> и не может быть назначен переменной, которая фиксирована для какого-либо другого типа; теперь вы знаете, что line на самом деле Result<String>, а не String, как ожидалось.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...