[英]How do you write an iterator to a File or Stdout (anything implementing Write)?
I have an iterator full of u8
's that I want to write to a file or stdout. 我有一个完整的u8
迭代器,我想将其写入文件或stdout。 Calling io::stdout().write_all(foo)
on my iterator gives me an expected type &[u8]
, and that I have an iterator type instead. 在我的迭代器上调用io::stdout().write_all(foo)
给我期望的类型&[u8]
,而我却拥有一个迭代器类型。 I understand why this doesn't work. 我了解为什么这行不通。
What I don't understand is how to change it so that it does work. 我不了解的是如何对其进行更改以使其起作用。 At first I tried adding a .collect()
to the end of my iterator, but then it says the trait bound &[u8]: std::iter::FromIterator<u8> is not satisfied
and a collection of type &[u8] cannot be built from an iterator over elements of type u8
. 最初,我尝试在迭代器的末尾添加.collect()
,但随后它说the trait bound &[u8]: std::iter::FromIterator<u8> is not satisfied
且a collection of type &[u8] cannot be built from an iterator over elements of type u8
。
It seems odd to me that Write doesn't provide a way of writing with an iterator, when Read provides a bytes()
function that returns an iterator. 当Read提供返回迭代器的bytes()
函数时,Write没有提供使用迭代器进行写入的方式对我来说似乎很奇怪。 What is the idiomatic way to do this? 惯用的方法是什么?
Here is my main function's contents: 这是我主要功能的内容:
io::stdout().write_all(
io::stdin().bytes().map(
|x| match x {
Ok(b) => b,
_ => panic!("There was an error reading from stdin"),
}
).repeat(3).collect()
);
The problem is that you want to build a Vec<u8>
, but are attempting to create a Vec<&u8>
. 问题是您要构建Vec<u8>
,但正在尝试创建Vec<&u8>
。 You can do the following: 您可以执行以下操作:
fn main() {
let array = [1u8, 2, 3];
let vector: Vec<u8> = array.iter().map(|i| *i).collect();
}
Note the .map(|i| *i)
part that allows to go from &u8
references to u8
values. 请注意.map(|i| *i)
部分,该部分允许从&u8
引用转到u8
值。
It seems odd to me that
Write
doesn't provide a way of writing with an iterator, whenRead
provides abytes()
function that returns an iterator. 当Read
提供返回迭代器的bytes()
函数时,Write
没有提供使用迭代器进行写入的方式对我来说似乎很奇怪。 What is the idiomatic way to do this? 惯用的方法是什么?
It does feel inconsistent, indeed, but you can certainly write the equivalent yourself. 确实确实感觉不一致,但是您当然可以自己编写等效的内容。
Something like: 就像是:
fn write_all<W: Write, I: Iterator<Item=u8>>(writer: &mut W, iter: I) {
const SIZE: usize = 1024;
let mut buffer = [0u8; SIZE];
let mut index = 0;
for i in iter {
buffer[index] = i;
index += 1;
if index == SIZE {
writer.write_all(&buffer);
}
}
writer.write_all(&buffer[..index]);
}
There are probably ways to make it more idiomatic, and I haven't tested the boundary conditions, but hopefully it should get you going. 可能有多种方法可以使它更加惯用,并且我还没有测试边界条件,但是希望它可以帮助您前进。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.