问题是这样的,今天我在用 SQLx 连接数据库时,用到了 SQLx 提供的 query_with
这么一个函数,它要求传入的 sql
、arguments
的生命周期一致。而当我编写下面的代码时,却报出了生命周期不够长的问题。
pub type SQLArgs<'a> = sqlx::any::AnyArguments<'a>;
pub fn build_where<'a>(condition: Condition) -> (String, SQLArgs<'a>)
pub fn query_with<'q, DB, A>(sql: &'q str, arguments: A) -> Query<'q, DB, A>
where
DB: Database,
A: IntoArguments<'q, DB>,
// Check sql statment
let select = DMLBuilder::build_wildcard_select("Genshin_characters");
let (where_, existed_args) = DMLBuilder::build_where(complicated_condition);
let limit = DMLBuilder::build_limit(1);
let query_xp_character = format!("{}{}{}", select, where_, limit);
assert_eq!(
query_xp_character,
r#"SELECT * FROM `Genshin_characters` WHERE ((`SEX` = ?) AND (`Region` IN (?, ?)) AND (`Vision` = ?)) OR (`Name` = ?) LIMIT 1"#
);
let mut conn = sqlx::AnyConnection::connect("sqlite://:memory:").await.unwrap();
conn.execute(
r#"
CREATE TABLE `Genshin_characters` (
id Integer Primary Key,
SEX varchar(20),
Region varchar(20),
Vision varchar(20),
Name varchar(20)
);
INSERT INTO `Genshin_characters` (SEX, Region, Vision, Name) VALUES
("FEMALE", "Liyue", "Pyro", "Xiangling")
"#,
)
.await
.unwrap();
let res = sqlx::query_with(&query_xp_character, existed_args)
.fetch_optional(&mut conn)
.await
.unwrap();
assert!(res.is_some());
let row = res.unwrap();
assert_eq!("Xiangling", row.get::<&str, &str>("Name"));
error[E0597]: `query_xp_character` does not live long enough
--> colos-rs-server/src/dao/sql/dml_builder.rs:292:36
|
292 | let res = sqlx::query_with(&query_xp_character, existed_args)
| ^^^^^^^^^^^^^^^^^^^ borrowed value does not live long enough
...
299 | }
| -
| |
| `query_xp_character` dropped here while still borrowed
| borrow might be used here, when `existed_args` is dropped and runs the destructor for type `AnyArguments<'_>`
|
= note: values in a scope are dropped in the opposite order they are defined
根据我的理解,query_xp_character
这个 String
的生命周期与这个函数一致,existed_args
的生命周期也是一样。并没法理解这个问题出在那里。
1
共 3 条评论, 1 页
评论区
写评论哦哦😯
--
👇
lan: 变量们会依照声明顺序的倒序drop,你这里的代码中有俩借用产生了依赖,调整声明顺序让被借用者后drop即可。
变量们会依照声明顺序的倒序drop,你这里的代码中有俩借用产生了依赖,调整声明顺序让被借用者后drop即可。
PS: 如果我这么写就可以通过编译