【问题标题】:How to return tokio_postgres ToSql type from closure in Rust?如何从 Rust 的闭包中返回 tokio postgres To Sql 类型?
【发布时间】:2021-11-02 03:56:25
【问题描述】:

我如何避免重复自己,将 ToSql 数据作为闭包传递,告诉 tokio-postgres 哪些数据列,从我的各种结构模型到 COPY/SELECT/etc?

例如,理想情况下我可以传递各种表/列参数,例如:

// see MRE, "copy_in" performs boilerplate to copy binary format in postgres table
copy_in(
    &mut client, // the postgres client setup in tokio
    "table_name", // meta info about what table/columns to insert
    &["col1", "col2", "col3", "col4"],
    &vec![Type::INT4, Type::VARCHAR, Type::INT4, Type::INT4],
    &rows_of_struct_data, // the vec of data I plan to insert
    // then here's the hard part: which fields to extract from each row... (not works)
    |m| &[&[&m.id], &[&m.name], &[&m.range_begin, &m.range_end]] as &[&[&(dyn ToSql + Sync)]]
  );

tokio_postgres 需要writing binary data during a copyVec<&(dyn ToSql + Sync)> 的类型,尽管硬编码将pushed 输入到 Vec 中的内容有效,但我很困惑如何传递一个动态决定 push 的参数。 .

对此我有两个想法,但是推荐的方法是什么?

  1. MRE 所示,我可以将闭包传递给我的复制函数,该函数返回每行要写入标准输入的哪些列,但我如何键入闭包以避免?:

应为&dyn ToSql + Sync,找到特征对象dyn ToSql

  1. 或者,如 MRE 所示,我可以将 Vec 传递给我的闭包,以便将列数据推送到每一行,但这有几个生命周期问题,例如:

row 的引用在此处转义异步闭包体

【问题讨论】:

    标签: rust closures rust-tokio tokio-postgres


    【解决方案1】:

    在我的两种方法中,我终于得到了 #1 的工作,尽管我不接受我自己的答案,以防出现更好的建议。

    这是工作的MRE

    这是我的理解中缺少的内容:

    • 我需要为每种类型的列返回一个 Vec,否则如果单个 Vec 同时包含 i32String,则违反了 ToSql 类型
    • 我需要返回 owned object不是引用,因为 Rust 中的函数无法返回它们拥有的引用。

    有兴趣了解纯函数式编程学习其他人可能会推荐的内容。这对理解如何使用闭包非常有帮助。 #2 方法有终身挑战,如果其他人对此有见解,我很感兴趣。

    【讨论】:

    • 感谢分享您的解决方案。我已将其构建为更惯用的形式 (playground)。如果您愿意,可以将其包含在您的答案中。您实际上并不需要为每个字段返回 Vec,您只需要以允许编译器推断它应该包含特征对象而不是具体引用的方式编写它。你的第二点是对的。
    • @kmdreko 可以随意编辑,这是一个值得称赞的伟大改进。不知道我是怎么错过的!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-05-21
    • 2011-05-30
    • 2021-07-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多