我试图了解如何编写正确的 Rust 代码,但我认为我可能高估了编译器理解对象生命周期的能力。这是我期望它工作的代码:
use std::path::Path;
use std::env;
use rusqlite::SqliteConnection;
struct SomeDatabase {
conn: SqliteConnection,
}
impl SomeDatabase {
fn getPath() -> &Path {
let path = env::home_dir().unwrap();
path.push("foo.sqlite3");
path.as_path()
}
fn open() -> SomeDatabase {
let path = SomeDatabase::getPath()
SomeDatabase { conn: SqliteConnection::open(path).unwrap() }
}
}
fn main() {
let db = SomeDatabase::open();
}
当我尝试编译它时,我收到一个关于缺少生命周期说明符的错误&Path
。我知道如果这从调用者那里获取了引用参数,它将具有与该引用相同的生命周期。但在这里,我所期望的是生命周期将附加到我将结果分配给的变量上。
我知道可以显式添加生命周期,但我不知道如何在这种情况下应用它们。编译器建议尝试'static
生命周期,但据我所知,这在这里没有意义,因为该函数的返回值的来源不是静态的。
现在,为了看看如果我尝试编译其余代码会发生什么,我将返回类型从&Path
to PathBuf
并打电话给as_path()
in open()
。这导致编译器输出这些错误:
src\main.rs:22:30: 22:52 error: the trait `core::marker::Sized` is not implemented for the type `[u8]` [E0277]
src\main.rs:22 SomeDatabase { conn: SqliteConnection::open(path).unwrap() }
^~~~~~~~~~~~~~~~~~~~~~
src\main.rs:22:30: 22:52 note: `[u8]` does not have a constant size known at compile-time
src\main.rs:22 SomeDatabase { conn: SqliteConnection::open(path).unwrap() }
^~~~~~~~~~~~~~~~~~~~~~
SqliteConnection::open()
返回一个Result<SqliteConnection, SqliteError>
以及里面唯一的字段SqliteConnection
is a RefCell
,所以我不明白这个关于字节数组的错误来自哪里。
那么,为什么事情没有按照我的预期工作,编写这段代码的最 Rusty 方法是什么?