当在gtk条目中按下Enter键时,我正试图用Diesel从数据库中获取对象。我的想法是在主函数中创建一个Diesel SQLite连接,然后在每次需要时借用它。
为此,我尝试使用一个非常简单的MVC。这个想法是将连接传递给所有的控制器并重用它。我知道生命周期在这里是必要的。
pub struct Controller<'a> {
pub connection: &'a SQLiteConnection,
pub search_entry: SearchEntry,
....
}
impl<'a> Controller<'a> {
pub fn new(conn: &'a SQLiteConnection) -> Self {
Self {
search_entry: SearchEntry::new(),
connection: conn,
....
}
}
pub fn init(&self) {
self.search_entry.connect_activate(|x| {
let need_it = diesel_table
.filter(column_id.eq(&x.get_text().unwrap()))
.first(self.connection)
.unwrap();
});
}
}
当编译时,我得到了这个:
error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements
--> src/lib.rs:44:44
|
44 | self.search_entry.connect_activate(|x| {
| ____________________________________________^
45 | | let need_it = diesel_table
46 | | .filter(column_id.eq(&x.get_text().unwrap()))
47 | | .first(self.connection)
48 | | .unwrap();
49 | | });
| |_________^
|
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the method body at 43:5...
--> src/lib.rs:43:5
|
43 | / pub fn init(&self) {
44 | | let need_it = diesel_table
46 | | .filter(column_id.eq(&x.get_text().unwrap()))
47 | | .first(self.connection)
48 | | .unwrap();
49 | | });
50 | | }
| |_____^
note: ...so that the types are compatible
--> src/lib.rs:44:44
|
44 | self.search_entry.connect_activate(|x| {
| ____________________________________________^
45 | | let need_it = diesel_table
46 | | .filter(column_id.eq(&x.get_text().unwrap()))
47 | | .first(self.connection)
48 | | .unwrap();
49 | | });
| |_________^
= note: expected `&&Controller<'_>`
found `&&Controller<'a>`
= note: but, the lifetime must be valid for the static lifetime...
note: ...so that the type `[closure@src/lib.rs:44:44: 49:10 self:&&Controller<'_>]` will meet its required lifetime bounds
--> src/lib.rs:44:27
|
44 | self.search_entry.connect_activate(|x| {
| ^^^^^^^^^^^^^^^^
此错误是因为函数connect_activate
有一个静态参数:fn connect_activate<F: Fn(&Self) + 'static>
。
我不想每次用户按下Intro键时都使用返回连接的函数来初始化连接。相反,我想借用这种联系。
最有效的方法是什么?
非常感谢。我希望你明白一切。
我想你需要一个Rc<SQLiteConnection>
除了OP提到的问题外,这个问题还包含其他各种代码问题,因此我将根据上面提供的信息提供一个完整的工作示例。对于未来的问题:请确保您的示例是独立的,并且不包含问题中提到的其他编译错误。这将使其他人更容易重现你的问题并回答问题。
#[macro_use] extern crate diesel;
use diesel::prelude::*;
table! {
diesel_table(id) {
id -> Integer,
column_id -> Text,
}
}
pub struct Controller<'a> {
pub connection: &'a SqliteConnection,
pub search_entry: SearchEntry,
}
pub struct SearchEntry;
impl SearchEntry {
fn new() -> Self {
SearchEntry
}
fn connect_activate<'a, F: Fn(&Self) + 'a>(&self, f: F) {
f(self)
}
fn get_text(&self) -> Option<&'static str> {
Some("foo")
}
}
impl<'a> Controller<'a> {
pub fn new(conn: &'a SqliteConnection) -> Self {
Self {
search_entry: SearchEntry::new(),
connection: conn,
}
}
pub fn init(&self) {
self.search_entry.connect_activate(|x| {
use self::diesel_table::dsl::*;
let need_it: (i32, String) = diesel_table
.filter(column_id.eq(&x.get_text().unwrap()))
.first(self.connection)
.unwrap();
});
}
}
解决OP中描述的错误的唯一相关更改是对connect_activate
:的以下更改
- fn connect_activate<F: Fn(&Self) + 'static>(&self, f: F) {
+ fn connect_activate<'a, F: Fn(&Self) + 'a>(&self, f: F) {