You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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让函数能兼容所有实现了Read trait的具体类型(如&[u8]、File等),这些类型均满足Sized约束,符合JsonStreamReader的要求。
  • 无需使用dyn Read作为JsonStreamReader的类型参数,因为JsonStreamReader需要持有具体的读取器实例,而非 trait 对象。

内容的提问来源于stack exchange,提问作者James McPherson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 19:20:24