私は適切な錆のコードを書く方法を理解しようとしていますが、私は私のオブジェクトの寿命を理解するコンパイラの能力のパワーを過大評価していると思います。私はそれが動作するように期待通りこれはコードです:関数から&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
に欠け寿命指定子に関するエラーが発生します。私はこれが呼び出し元からの参照パラメータを取るかどうかを知っている、それは参照が持っているのと同じ生涯かかるだろう。ここで私が期待していたのは、生涯が変数に結びついて、結果を割り当てることです。
私は寿命を明示的に追加することができますが、私はこの場合にどのように適用するのか分かりません。コンパイラは寿命が'static
であることを示唆していますが、この関数の戻り値のソースが静的ではないため、ここではわかりません。ちょうど私が残りのコードをコンパイルしようとした場合には何が起こったかを確認するためにしようとする今、
PathBuf
へ
&Path
から戻り値の型を変更し、
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
あるResult<SqliteConnection, SqliteError>
を返すとし、そのバイト配列については、このエラーはどこから来ている私は理解していません。
私は期待どおりに動作していないのですが、このコードを書いた最もラスティックな方法は何ですか?
最初のケースでは、関数内で作成されたものへの参照を返していますが、SomeDatabaseのメンバー関数getPath()を作成すると、コンパイラはSomeDatabaseのインスタンスまで&Pathを保持できるほどスマートです範囲外になる。私は参照の寿命がgetPath()(getPath()が関連する関数である場合)を呼び出している関数に属していることをコンパイラに伝える方法があるかどうかを尋ねています。ライフタイムコードは、参照を保持する変数がopen()の有効範囲外になるまで保持する必要があります。 –
また、as_path()を終了すると、 "expected '&_'、 'std :: path :: PathBuf'(期待された&-ptr、構造体の 'std :: path'が見つかりました。 :: PathBuf ') –
@AustinWagner変数 'path'は' getPath() 'メソッドの本体に定義されています。戻り値を返さない限り、この関数本体のスコープの終わりで終わります。あなたのケースでは、 'PathBuf'を' getPath() '関数に返す代わりの手段はありません。 – Levans