Rust中传递<R: Read>对象给子函数?编译错误求助
Rust中传递JsonStreamReader到处理函数的编译错误解决
我在Rust中实现将JSON数组拆分为n条记录的功能,使用struson库的JsonStreamReader。在fn main()中创建JsonStreamReader对象后传递给处理函数时,遇到了编译错误:
最初的错误:
Compiling json-split v0.1.0 (/mnt/c/Users/jmcpherson/code/playground/rust/json-split) error[E0782]: trait objects must include the `dyn` keyword --> src/main.rs:33:52 | 33 | fn process_stream(theReader: &mut JsonStreamReader<Read>) -> Result<Vec<Map<Keys, Values>> , Box<dyn std::error::Error>> { | ^^^^ | help: add `dyn` keyword before this trait | 33 | fn process_stream(theReader: &mut JsonStreamReader<dyn Read>) -> Result<Vec<Map<Keys, Values>> , Box<dyn std::error::Error>> { | +++ For more information about this error, try `rustc --explain E0782`. error: could not compile `json-split` (bin "json-split") due to previous error
按照rustc提示修改后,又出现新错误:
jmcp:~/code/playground/rust/json-split$ cargo build Compiling json-split v0.1.0 (/mnt/c/Users/jmcpherson/code/playground/rust/json-split) error[E0277]: the size for values of type `(dyn std::io::Read + 'static)` cannot be known at compilation time --> src/main.rs:33:30 | 33 | fn process_stream(theReader: &mut JsonStreamReader<dyn Read>) -> Result<Vec<Map<Keys, Values>> , Box<dyn std::error::Error>> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `(dyn std::io::Read + 'static)` note: required by a bound in `JsonStreamReader` --> /home/jmcp/.cargo/registry/src/index.crates.io-6f17d22bba15001f/struson-0.3.0/src/reader.rs:1752:29 | 1752 | pub struct JsonStreamReader<R: Read> { | ^ required by this bound in `JsonStreamReader` For more information about this error, try `rustc --explain E0277`. error: could not compile `json-split` (bin "json-split") due to previous error
问题解答
不需要在fn main()中将reader声明为static,问题出在处理函数的参数定义逻辑上:
JsonStreamReader<R>的泛型参数R默认要求实现Sized trait(Rust泛型的隐式约束),而dyn Read属于动态大小类型(DST),不满足该约束,因此会触发第二个编译错误。
正确的解决方式是将处理函数定义为泛型函数,让编译器在调用时自动推导具体的Read实现类型:
use std::collections::HashMap; use std::io::Read; use struson::reader::{JsonStreamReader, JsonReader}; // 用泛型R代替dyn Read,自动满足Sized约束 fn process_stream<R: Read>(the_reader: &mut JsonStreamReader<R>) -> Result<Vec<HashMap<String, serde_json::Value>>, Box<dyn std::error::Error>> { // 初始化JSON数组读取 the_reader.begin_array()?; let mut records = Vec::new(); // 遍历数组元素 while the_reader.has_next()? { let value = the_reader.read_value()?; if let serde_json::Value::Object(obj) = value { records.push(obj); // 此处可添加拆分逻辑(如每n条记录执行一次处理) } } the_reader.end_array()?; Ok(records) } fn main() -> Result<(), Box<dyn std::error::Error>> { // 示例:从字符串创建Read实例 let json_data = r#"[{"id":1},{"id":2},{"id":3}]"#; let mut reader = JsonStreamReader::new(json_data.as_bytes()); let result = process_stream(&mut reader)?; println!("{:?}", result); Ok(()) }
关键说明
- 泛型参数
R: Read让函数能兼容所有实现了Readtrait的具体类型(如&[u8]、File等),这些类型均满足Sized约束,符合JsonStreamReader的要求。 - 无需使用
dyn Read作为JsonStreamReader的类型参数,因为JsonStreamReader需要持有具体的读取器实例,而非 trait 对象。
内容的提问来源于stack exchange,提问作者James McPherson
相关产品推荐
相关产品推荐

