rust - if else 借入时临时价值下降
问题描述
我正在使用 Rusqlite,它可以让你做这样的查询:
statement.query_row(params!([1, 2, 3]), ...);
params!()
定义如下:
macro_rules! params {
() => {
$crate::NO_PARAMS
};
($($param:expr),+ $(,)?) => {
&[$(&$param as &dyn $crate::ToSql),+] as &[&dyn $crate::ToSql]
};
}
这很好用,但在某些情况下,我想做这样的事情:
statement.query_row(if x { params![1, 2, 3] } else { params![4, 5] }, ...
不幸的是它不起作用 - 你得到一个temporary value dropped while borrowed
错误。我将问题简化为(操场):
fn main() {
foo(&[&1, &2, &3]); // Fine!
let x = 1;
let y = true;
let a = if y {
&[&x, &2, &3]
} else {
&[&5, &6, &7]
};
foo(a); // Error
}
fn foo(_x: &[&i32]) {
}
这是有道理的,但它很烦人。我目前的解决方法基本上是这样的:
let params_a = params![1, 2, 3];
let params_b = params![4, 5];
statement.query_row(if x { params_a } else { params_b }, ...
但这有点糟糕。有没有更好的办法?
解决方案
在 Rust 中,需要创建一个新绑定来延长临时对象的生命周期是很常见的。您的解决方案可能是最好的方法。
板条箱的创造者rusqlite
显然没有预料到这种用法——而且他们并没有让它变得容易。您可以创建自己的宏来封装值而不是返回引用,但这似乎并不值得。
您也可以将调用移动statement.query_row
到条件块中:
if x {
statement.query_row(params![1, 2, 3]);
} else {
statement.query_row(params![4, 5]);
}
这将避免创建您不需要的参数对象。
推荐阅读
- swift - 错误:无法查找符号:Swift.Task.Handle 的名义类型描述符尝试使用 Xcode 12.5 beta / Swift 5.5 进行异步/等待
- azure-devops - 是否可以参数化阶段条件 Azure DevOps Yaml 中的值
- c# - 如何使用可可和c#在xcode中的故事板中制作菜单
- css - CSS:防止内容增加父级相对于另一个父级的宽度
- arrays - 在递增函数中的值之前返回输出的函数指针数组
- javascript - Ant Design 定制轮播
- asp.net - Web.Config Url 重写工作,但重定向不起作用
- .net - Azure TimerTrigger 函数在升级到 .Net core 3.1 后抛出异常。函数的监听器无法启动
- sql - 如何连接两个没有公共列的 SQL Server 表
- command-line-interface - Linux mv:目标不是目录