将变量重复传递给函数(它会改变所述变量)

rjc*_*upe 2 ownership move-semantics rust

我正在玩Rust,并且可能咬得比我可以咀嚼的多得多,我正在尝试编写一个模块来封装我应用程序其余部分的数据库流量.我正在努力解决的代码如下:

pub fn create_statement(cypher: &str, params: &HashMap<&str, &str>) -> rusted_cypher::Statement {
    let mut statement = rusted_cypher::Statement::new(cypher);
    for (field, value) in params.iter() {
        statement.with_param(field.to_owned(), value.to_owned());
    }
    return statement;
}
Run Code Online (Sandbox Code Playgroud)

这会出现以下错误:error[E0382]: use of moved value: statement.我认为,我的搜索引导我达到这意味着什么(Statement结构不可复制,因此被移动,然后......实际上不再可访问,我猜?),但我不确定如何绕过它.有人能指出我的解决方案吗?

Pet*_*all 5

我之前没有使用过这个API,但根据其文档:

此方法self使用添加的参数来使用并返回它,因此绑定不需要是可变的.

正如你所说的那样,结构不是"不可复制的",而是with_param有意地以这样的方式编写方法,即它移动值并取得所有权 - 我们也可以说它消耗它.在构建器样式的API中,使用值是常见的事情,因为它可以防止您出现意外的半构建对象.每个构建器方法都将使用该对象,在此期间没有其他任何东西可以访问它,然后在完成后返回它,以便您可以继续使用它.从文档:

let statement = Statement::new("MATCH n RETURN n")
    .with_param("param1", "value1")?
    .with_param("param2", 2)?
    .with_param("param3", 3.0)?;
Run Code Online (Sandbox Code Playgroud)

每次通话都会with_param消耗statement然后返回,这样您就可以with_param再次通话.

这有点棘手的地方是,结果with_param不是a Statement,而是a Result<Statement, JsonError>.显然添加参数可能会导致错误,因此结果将被包装以适应这种可能性.这就是?s的用途 - 它们将结果解包到底层值中,否则如果无法完成则传播错误.

作为已经建议的其他答案之一,更好的解决方法是只使用该set_parameters方法,这将一次性设置它们.

另一种方法是使用每次调用的返回值with_param:

pub fn create_statement(cypher: &str, params: &HashMap<&str, &str>) -> rusted_cypher::Statement {
  let mut statement = rusted_cypher::Statement::new(cypher);
  for (field, value) in params.iter() {
      statement = statement.with_param(field.to_owned(), value.to_owned()).unwrap();
  }
  statement
}
Run Code Online (Sandbox Code Playgroud)

使用返回值时,您可以再次访问该值,以便继续使用它.

请注意,我曾经unwrap()从中获取值Result.这不是一个好习惯,因为如果结果是错误会导致恐慌.我在这里做了这个,专注于解释移动语义,而不是错误处理,这本身就是一个主题.