反复将变量传递给函数(改变所述变量)
Passing a variable to a function (which alters said variable) repeatedly
我正在尝试使用 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;
}
这会产生以下错误:error[E0382]: use of moved value: statement
。我认为,我的搜索让我明白了这意味着什么(Statement
结构不可复制,因此被移动,然后......实际上不再可访问,我猜?),但我不确定如何绕过它。谁能指出解决方案的方向?
虽然这没有回答您关于以与当前代码相同的方式传递可变值的基本问题。
rusted-cypher::Statement
有一个 set_parameters
方法,该方法将 &BTreeMap<String, T>
作为其唯一参数。
您可以在 rusted-cypher's source code.
中看到此功能
一个可能的实现:
pub fn create_statement(cypher: &str, params: &BTreeMap<&str, &str>) -> rusted_cypher::Statement {
let mut statement = rusted_cypher::Statement::new(cypher);
statement.set_parameters(params);
statement
}
我以前没用过这个 API 但是,根据 its documentation:
This method consumes self
and returns it with the parameter added, so the binding does not need to be mutable.
正如您所说,结构不是 "not copyable",而是 with_param
方法是有意编写的 移动 价值并获得所有权 - 我们也可以说它 消耗 它。在构建器风格 API 中使用该值是一件很常见的事情,因为它可以防止您意外地放置一半构建的对象。每个构建器方法都将使用该对象,在此期间没有其他任何东西可以访问它,然后 return 它完成后,您可以继续使用它。来自文档:
let statement = Statement::new("MATCH n RETURN n")
.with_param("param1", "value1")?
.with_param("param2", 2)?
.with_param("param3", 3.0)?;
每次调用 with_param
都会消耗 statement
,然后 return 消耗它,这样您就可以再次调用 with_param
。
这有点棘手的是 with_param
的结果不是 Statement
,而是 Result<Statement, JsonError>
。显然,添加参数可能会导致错误,因此结果会被打包以适应这种可能性。这就是 ?
的用途 - 它们将结果解包为基础值,或者如果无法完成则传播错误。
正如已经建议的其他答案之一,更好的解决方法是只使用 set_parameters
方法,这将一次性设置它们。
另一种方法是使用每次调用 with_param
:
的 return 值
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
}
当您使用 return 值时,您可以再次访问该值,因此您可以继续使用它。
请注意,我使用 unwrap()
从 Result
中获取值。这 不是 好的做法,因为如果结果是错误的,它会导致恐慌。我在这里这样做是为了专注于解释移动语义而不离题到错误处理,这本身就是一个主题。
我正在尝试使用 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;
}
这会产生以下错误:error[E0382]: use of moved value: statement
。我认为,我的搜索让我明白了这意味着什么(Statement
结构不可复制,因此被移动,然后......实际上不再可访问,我猜?),但我不确定如何绕过它。谁能指出解决方案的方向?
虽然这没有回答您关于以与当前代码相同的方式传递可变值的基本问题。
rusted-cypher::Statement
有一个 set_parameters
方法,该方法将 &BTreeMap<String, T>
作为其唯一参数。
您可以在 rusted-cypher's source code.
中看到此功能一个可能的实现:
pub fn create_statement(cypher: &str, params: &BTreeMap<&str, &str>) -> rusted_cypher::Statement {
let mut statement = rusted_cypher::Statement::new(cypher);
statement.set_parameters(params);
statement
}
我以前没用过这个 API 但是,根据 its documentation:
This method consumes
self
and returns it with the parameter added, so the binding does not need to be mutable.
正如您所说,结构不是 "not copyable",而是 with_param
方法是有意编写的 移动 价值并获得所有权 - 我们也可以说它 消耗 它。在构建器风格 API 中使用该值是一件很常见的事情,因为它可以防止您意外地放置一半构建的对象。每个构建器方法都将使用该对象,在此期间没有其他任何东西可以访问它,然后 return 它完成后,您可以继续使用它。来自文档:
let statement = Statement::new("MATCH n RETURN n")
.with_param("param1", "value1")?
.with_param("param2", 2)?
.with_param("param3", 3.0)?;
每次调用 with_param
都会消耗 statement
,然后 return 消耗它,这样您就可以再次调用 with_param
。
这有点棘手的是 with_param
的结果不是 Statement
,而是 Result<Statement, JsonError>
。显然,添加参数可能会导致错误,因此结果会被打包以适应这种可能性。这就是 ?
的用途 - 它们将结果解包为基础值,或者如果无法完成则传播错误。
正如已经建议的其他答案之一,更好的解决方法是只使用 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
}
当您使用 return 值时,您可以再次访问该值,因此您可以继续使用它。
请注意,我使用 unwrap()
从 Result
中获取值。这 不是 好的做法,因为如果结果是错误的,它会导致恐慌。我在这里这样做是为了专注于解释移动语义而不离题到错误处理,这本身就是一个主题。