【问题标题】:How to conditionally create a serializer and sequence? (Option<SerializeSeq>)如何有条件地创建序列化器和序列? (选项<SerializeSeq>)
【发布时间】:2021-11-29 12:01:02
【问题描述】:

我正在尝试处理来自通道的数据,因此无法一次序列化整个结构。事实上,它不会都适合记忆。我遇到的问题是我无法创建Option&lt;SerializeSeq&gt;,因为该对象依赖于Serializer(它的寿命不够长)。我想一起初始化它们,或者根本不初始化:

use serde::ser::{SerializeSeq, Serializer};
fn process_stream(output: bool) -> serde_json::Result<()> {
    let rows = /* whatever iterator */ "serde".chars();

    let mut seq = if output {
        let out = std::io::stdout();
        let mut ser = serde_json::Serializer::new(out);
        let seq = ser.serialize_seq(None)?
        Some(Ok(seq))
    } else {
        None
    }.transpose()?;

    for row in rows {
        //process_data(row);
        if let Some(seq) = &mut seq {
            seq.serialize_element(&row)?;
        }
    }

    if let Some(seq) = seq {
        seq.end()?;
    }
    Ok(())
}

here的原始代码sn-p。)

问题是:ser does not live long enough。但我不想在外部范围内初始化ser,因为它可能未启用(并且它的编写者会创建或截断不应创建的文件)。我尝试将serseq 作为一个元组返回。我尝试将它们放在一个辅助结构中,但我无法弄清楚所有模板参数和生命周期。

如何根据条件初始化serde序列化器和序列并存储在Option中?

【问题讨论】:

  • 不知道你有没有试过,但显而易见的想法是在外部范围内声明 ser,但只在需要时初始化它:play.rust-lang.org/…
  • @user4815162342 谢谢,我没有意识到这是允许的!
  • 即使不是,您仍然可以使用let mut ser = None 后跟ser = Some(Serializer::new(...)) 并用作ser.unwrap().serialize_element(&amp;row) 来伪造它。那会更难看,因为它需要一个误导性的unwrap(),而实际上可能永远不会触发。
  • @user4815162342 我尝试了类似的方法,包括该代码和使用mapif let 的更惯用的版本。它没有用,但我可能没有完全按照您的想法编写它......这种类型的代码可能会以多种方式失败。除了一个生命周期不够长的变量之外,我不允许使用对局部变量的引用来构造seq。或函数参数。或者可以在借用时丢弃临时的。
  • This is 我的想法。您可以使用对本地的引用来构造seq,只要它比seq 寿命长。在您的实验中,您可能没有使用as_mut(),没有它,unwrap() 会将seq 移出选项。这导致另一个“活得不够长”的错误,似乎以一种非常令人困惑的方式击败了范围更广的seq。修复是微不足道的,但只有在您了解问题的根源之后。

标签: rust serde


【解决方案1】:

确保 ser 在 if 主体之外声明它不会被过早删除:

let mut ser;
let mut seq = if output {
    let out = std::io::stdout();
    ser = serde_json::Serializer::new(out);
    let seq = ser.serialize_seq(None)?;
    Some(Ok(seq))
} else {
    None
}.transpose()?;

【讨论】:

  • 谢谢!我不敢相信这行得通。我不知道 rust 允许在没有这样赋值的情况下声明,尽管我认为它非常安全。
猜你喜欢
  • 2016-08-08
  • 2016-03-23
  • 2020-02-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多