RwLockWriteGuard未继承内部类型trait,如何实现std::io::Read?
解决方案
方法1:直接解引用守卫
Tokio的RwLockWriteGuard实现了DerefMut,可以通过&mut *stream直接获取内部I2pStream的可变引用,而std::io::Read trait已为&mut T(当T实现Read时)实现,直接传递这个引用即可满足要求:
let mut stream = wrapped_stream.write().await; // 解引用得到内部流的可变引用,适配Read trait要求 let iterator = serde_json::Deserializer::from_reader(&mut *stream).into_iter::<serde_json::Value>(); for item in iterator { // 处理每个JSON对象 }
方法2:自定义包装类型实现Read
如果需要更封装的写法,可以创建一个newtype包装RwLockWriteGuard,手动为其实现Read trait:
use std::io::{Read, Result}; use tokio::sync::RwLockWriteGuard; // 自定义包装类型 struct GuardReader<'a, T>(RwLockWriteGuard<'a, T>); // 转发Read调用给内部的流类型 impl<'a, T: Read> Read for GuardReader<'a, T> { fn read(&mut self, buf: &mut [u8]) -> Result<usize> { self.0.read(buf) } } // 使用示例 let stream = wrapped_stream.write().await; let reader = GuardReader(stream); let iterator = serde_json::Deserializer::from_reader(reader).into_iter::<serde_json::Value>(); for item in iterator { // 处理逻辑 }
问题原因
你能直接调用stream.read()是因为RwLockWriteGuard实现了DerefMut trait,Rust会自动解引用到内部的I2pStream,从而调用它的read方法。但serde_json::Deserializer::from_reader要求参数是直接实现了Read trait的类型,而RwLockWriteGuard本身并没有为内部类型自动派生Read trait实现——Rust不会为外部包装类型自动实现所有trait,除非有专门的 blanket 实现(Tokio的锁守卫并没有提供这样的实现)。
内容的提问来源于stack exchange,提问作者philhob
相关产品推荐
相关产品推荐

