提问人:curious 提问时间:3/16/2023 最后编辑:cafce25curious 更新时间:3/16/2023 访问量:106
如何在 BufReader 中包装同时实现读取和写入的结构的读取部分?
How can I wrap the read portion of a struct which implements both Read and Write in a BufReader?
问:
我正在尝试从对象中读取一行。我的第一反应是将它包装在一个 中,但问题是我需要能够将我的调用与调用交错,并且我不能使用底层流,同时对它有一个可变的引用。解决这个问题的惯用方法是什么?rustls::StreamOwned
BufReader
read_line()
write()
BufReader
示例代码:
let stream: rustls::StreamOwned = //blah
let r = BufReader::new(stream) // Can't pass a reference here since &rustls::StreamOwned doesn't implement the read trait
loop {
let line: String;
r.read_line(&line);
stream.write(b"ping"); // Will fail to compile since r still owns the stream
}
类似问题:
不同之处在于,我正在处理的类型的引用类型没有实现该特征,因此我不能简单地将引用传递给 .Read
BufReader
答:
3赞
rodrigo
3/16/2023
#1
问题的解决方案来自不包含值的实现,而是实现 的泛型类型。在你的例子中,这是一个字面意思,实际类型不会丢失,因为你使用了BufReader,或者我应该说一个.BufReader
Read
Read
StreamOwned
BufReader<StreamOwned>
您可以使用 BufReader::get_mut()
访问内部值。文档中有一条注释说:
不建议直接从基础阅读器读取。
这是有道理的,因为直接读取会弄乱缓冲流,但它没有说明使用所包含对象的其他非读取功能,就像你的例子中写流的一半一样。
TL的;DR:写一些类似的东西(模拟的操场):
fn main() {
let stream = StreamOwned;
let mut r = BufReader::new(stream);
loop {
let mut line = String::new();
r.read_line(&mut line);
r.get_mut().write(b"ping"); // now it compiles!
}
}
评论
0赞
curious
3/16/2023
是的,BufReader 包含“实现读取的类型”并没有混淆,因此我在最初的问题中写了“不实现读取特征”。 我理解为什么 BufReader 需要对底层阅读器的独占访问权限,但这不是我的问题。 确实是解决方案,但每次我想以可变方式使用它时,创建对基础对象的可变引用似乎有点笨拙。Which makes sense because that direct read would mess up the buffered stream,
r.get_mut().write(b"ping");
0赞
rodrigo
3/16/2023
@curious:是的,我承认它看起来有点笨拙。如果你经常使用它,或者如果你想要一个 for it,那么创建一个 newtype 包装并实现 and for it 可能是有意义的。但对于常规使用,我认为这已经足够了。BufWriter
BufReader<StreamOwned>
BufRead
Write
评论
Read
RefCell