Rust 我如何退还a&;amp;;;函数的路径?
我试图理解如何编写正确的Rust代码,但我认为我可能高估了编译器理解对象生命周期的能力。这是我所期望的代码:Rust 我如何退还a&;amp;;;函数的路径?,rust,Rust,我试图理解如何编写正确的Rust代码,但我认为我可能高估了编译器理解对象生命周期的能力。这是我所期望的代码: use std::path::Path; use std::env; use rusqlite::SqliteConnection; struct SomeDatabase { conn: SqliteConnection, } impl SomeDatabase { fn getPath() -> &Path { let path =
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
上缺少生存期说明符的错误。我知道,如果它从调用方获取了一个引用参数,那么它将使用与该引用相同的生存期。但在这里,我期望的是,生命周期将附加到我将结果分配给的变量
我知道可以显式地添加生命周期,但我不知道如何在这种情况下应用它们。编译器建议尝试使用“静态”
生存期,但据我所知,这在这里没有意义,因为此函数返回值的源不是静态的
现在,为了看看如果我试图编译其余的代码会发生什么,我将返回类型从&Path
更改为PathBuf
,并在open()
中调用as_Path()
。这导致编译器输出以下错误:
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()
返回一个结果
,而SqliteConnection
中唯一的字段是一个RefCell
,因此我不明白这个关于字节数组的错误来自何处
那么,为什么事情不能如我所期望的那样工作呢?写这段代码最生疏的方式是什么 在第一种情况下,您正在创建一个值,然后尝试返回对该值的引用。但是,由于您没有将该值存储在任何位置,因此在函数结束后它会被销毁。如果它被允许的话,它将在释放bug后使用 它建议返回一个
&'static Path
的原因是函数在任何生存期内都没有参数化,因此您可以确保的唯一生存期超过任何想要使用返回值的对象的生存期将是'static
您需要直接返回路径buf
,而不是路径
,这是正确的
我不太清楚为什么会出现[u8]
大小的错误
您根本不需要调用“as_path()”
SqliteConnection::open
接受一个实现AsRef
(AsRef
有点像Into
),并且PathBuf
确实实现了这个特性。我意识到,在第一种情况下,我返回了对函数内部创建的某个对象的引用,但如果我使用getPath()作为SomeDatabase的一个成员函数,编译器足够聪明,可以保持&Path,直到SomeDatabase的实例超出范围。我在问是否有办法告诉编译器引用的生存期属于调用getPath()的函数(在getPath()是关联函数的情况下)。它的生命周期代码应该一直持续到保存引用的变量在open()中超出作用域为止。还必须补充的是,如果我将其保留为_path(),我会得到一个不匹配的类型错误:“expected'&&&,find'std::path::PathBuf'(expected&-ptr,find struct'std::path::PathBuf')@AustinWagner变量path
是在getPath()
方法的主体中定义的,除非您返回它,否则它的生存期将在此函数主体范围的末尾结束。无法避免此规则。对于getPath()
function.@AustinWagner如果我将getPath设为成员函数[…],编译器将保留&Path,直到实例[…]超出范围-这是。您也有同样的问题,即当函数返回时,局部变量会被删除,因为没有任何东西拥有它。SqliteConnection::open
接受一个实现的值-请注意,对实现AsRef
的类型的引用。我认为这可能是发生大小错误的原因。这图书馆方面似乎做出了一个奇怪的决定。。。