【问题标题】:What's the idiomatic way to pass types in Rust?在 Rust 中传递类型的惯用方式是什么?
【发布时间】:2021-05-19 05:21:58
【问题描述】:

我创建了一个连接类型,即

let mut conn = Connection::open("sqlite.db").unwrap();

然后我将该类型与向量一起传递给我的 save_all 函数,如下所示:

pub fn save_all(conn: &mut Connection,
                vehicles: Vec<Vehicle>) -> Result<(), Error> {
    let tx = conn.transaction()?;
    for v in vehicles {
        let sql: &str =
            "INSERT INTO local_edits (vehicle_id, make, model, color)
                 VALUES (:vehicle_id, :make, :model, :color)";
        let mut statement = tx.prepare(sql)?;
        statement.execute(named_params! {
                ":vehicle_id": v.vehicle_id,
                ":make": v.make,
                ":model": v.model,
                ":color": v.color})?;
    };
    tx.commit()?;
    return Ok(());
}

此代码似乎可以正常工作。这段代码真的正确吗?

如果我没有在save_all 函数中创建conn 类型&mut Connection,则代码不会为我编译。它告诉我:

Cannot borrow immutable local variable `conn` as mutable

我不太清楚如何理解。

将 conn 的“引用”传递给我的 save_all 函数是否正确?

我不想将所有权转让给此函数。我想我只是想让函数借用连接。

【问题讨论】:

  • 这里有几个问题,你应该问 code_review 而不是 SO。回答最明确的问题:&amp;mut 不会“转让所有权”,而是让函数拥有对其的临时独占访问权,这是连接和类似资源的常见模式。

标签: design-patterns rust rusqlite


【解决方案1】:

不能将不可变的局部变量 conn 借用为可变的

&amp;mut Connection 中的 mut 是必需的,因为您在 conn 上调用 transaction,这需要可变引用。另请参阅 documentation for this API callI,它需要 &amp;mut self

借款与所有权转让

如果您想稍后再次使用连接,借用似乎是正确的方法。如果您要转移连接的所有权,则必须将其作为结果的一部分再次返回,以便以后重新使用它(因为 rust 中的仿射类型如何工作)。这比仅仅借用连接更不符合人体工程学。

【讨论】:

  • 如果我创建一个具有 Connection 成员的结构并使用我的 save_all 函数创建该结构的 impl 会怎样。这样,该结构永久拥有该连接。这种模式在 Rust 中会被认为是可接受的吗?5
  • @Beebunny 当然。尽管您的结构的方法需要采用 &amp;mut self 才能以您想要的方式使用连接。如果它采用&amp;self,那么该方法中的连接将是不可变的。
  • 优秀。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-08-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-06
相关资源
最近更新 更多