反复将变量传递给函数(更改所述变量) [英] Passing a variable to a function (which alters said variable) repeatedly

查看:110
本文介绍了反复将变量传递给函数(更改所述变量)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在玩Rust,并且可能付出的努力远远超过了我可以咀嚼的程度,我正在尝试编写一个模块,该模块将封装我的数据库流量以供其他应用程序使用.我正在努力的代码如下:

I'm having a play with Rust and, probably biting off far more than I can chew, am trying to write a module that will encapsulate my database traffic for the rest of the application. The code I'm struggling with is the following:

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;
}

这将产生以下错误:error[E0382]: use of moved value: statement.我想我的搜索使我明白了这是什么意思(Statement结构不可复制,因此被移动,然后……实际上不再可访问,我想是吗?),但是我不确定如何绕开它.谁能指出我的解决方案方向?

This gives the following error: error[E0382]: use of moved value: statement. My searching has, I think, lead me to what this means (the Statement struct is not copyable, thus gets moved and is then ... effectively no longer accessible, I guess?), but I'm not sure how to get around it. Can anyone point me in the direction of a solution?

推荐答案

根据

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

This method consumes self and returns it with the parameter added, so the binding does not need to be mutable.

正如您所说的,该结构不是不可复制的",而是with_param方法是故意编写的,其移动值并获得所有权-我们也可以说它消费.在构建器样式的API中,使用该值是很常见的事情,因为它可以防止意外生成的半成品对象随处可见.每个构建器方法都会使用该对象,在此期间,其他任何人都无法访问该对象,然后在完成后将其返回,以便您可以继续使用它.从文档中:

It isn't, as you say, that the struct is "not copyable", it's that the with_param method is intentionally written in such a way that it moves the value and takes ownership - we can also say that it consumes it. Consuming the value is a common thing to do in a builder-style API because it prevents you from having accidental half-built objects lying around. Each builder method will consume the object, during which time nothing else can access it, and then return it when it's finished so you can continue using it. From the documentation:

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

每次调用with_param都会消耗statement,然后返回它,以便您可以再次调用with_param.

Each call to with_param consumes statement and then returns it so you can call with_param again.

有点棘手的地方是with_param的结果不是Statement,而是Result<Statement, JsonError>.显然,添加参数可能会导致错误,因此将结果打包以适应这种可能性.这就是?的作用-将结果解包为基础值,或者传播无法完成的错误.

Where this gets a bit tricky is that the result of the with_param is not a Statement, but a Result<Statement, JsonError>. Apparently adding a parameter could cause an error so the result is wrapped up to accommodate that possibility. That's what the ?s are for - they unwrap that result into the underlying value, or else propagate the error if that can't be done.

正如已经提出的其他答案之一,一个更好的解决方法是只使用set_parameters方法,这将使它们一次完成设置.

As one of the other answers already suggested, a better fix is to just use the set_parameters method, which will set them all in one go.

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

Another way to do it would be to use the return value of each call to 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
}

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

When you use the return value, you have access to the value again, so you can keep on using it.

请注意,我使用unwrap()Result获取值.这不是一个好习惯,因为如果结果错误,它将引起恐慌.在这里,我专注于解释移动语义,而不会涉及错误处理,这本身就是一个话题.

Notice that I used unwrap() to get the value from the Result. This is not good practice because it will cause a panic if the result is an error. I have done this here to focus on explaining move semantics without a digression into error handling, which is a topic by itself.

这篇关于反复将变量传递给函数(更改所述变量)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆