如何从函数返回& Path?

时间:2015-09-06 01:44:12

标签: rust

我试图理解如何编写正确的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更改为PathBuf并在{{as_path()中调用open() 1}}。这导致编译器输出这些错误:

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内唯一的字段是RefCell,所以我不明白有关字节数组的错误来自哪里从

那么,为什么没有像我期望的那样工作,以及编写此代码最生锈的方式是什么?

1 个答案:

答案 0 :(得分:7)

在第一种情况下,您正在创建一个值,然后尝试返回对它的引用。但是由于你不是在任何地方存储这个值,它会在函数结束后被破坏。如果允许的话,那就是免费使用后的错误。

它建议返回&'static Path的原因是因为该函数在任何生命周期内都没有参数化,因此唯一可以确定任何想要使用返回值的生命周期为{{1 }}

你是正确的,你需要直接返回'static而不是PathBuf

我不太清楚为什么会收到&Path大小的错误。

你不需要打电话给#34; as_path()&#34;一点都不[u8]采用实现SqliteConnection::open的值(AsRef<Path>有点像AsRef),Into确实实现了该特征。