如何从函数返回 &Path?

2024-01-15

我试图了解如何编写正确的 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 方法是什么?


在第一种情况下,您正在创建一个值,然后尝试返回对其的引用。但由于您没有将该值存储在任何地方,因此它会在函数结束后被销毁。如果允许的话,这将是一个释放后使用错误。

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

您是正确的,您需要返回PathBuf直接代替&Path.

我不太确定你为什么会得到[u8]大小错误。

您根本不需要调用“as_path()”。SqliteConnection::open取一个实现的值AsRef<Path> (AsRef有点像Into), and PathBuf确实实现了这个特性。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何从函数返回 &Path? 的相关文章

随机推荐