Почему при передаче tokio_ postgres :: Transaction в качестве ссылки требуется указать анонимное время жизни? - PullRequest
0 голосов
/ 18 июня 2020

Я использую tokio_ postgres для подключения к базе данных и пытаюсь начать транзакцию

let trans = client.transaction().await.unwrap();
trans.query("select * from abc", &[]).await.unwrap();
// ...
trans.commit().await.unwrap();

Все работает как положено. Теперь я хочу поместить код между trans.query и trans.commit в отдельную функцию

async fn tx_work(trans: &tokio_postgres::Transaction) {
    trans.query("select * from abc", &[]).await.unwrap();
    // ...
    trans.commit().await.unwrap();
}

и вызвать его в main:

let trans = client.transaction().await.unwrap();
tx_work(&trans).await.unwrap();

Код не компилировать:

error[E0726]: implicit elided lifetime not allowed here
   --> src/abc.rs:209:28
    |
209 | async fn tx_work(trans: &tokio_postgres::Transaction) {
    |                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^- help: indicate the anonymous lifetime: `<'_>`


Это не помогло:

async fn tx_work<'a>(trans: &'a tokio_postgres::Transaction)

Что мне делать?

1 Ответ

2 голосов
/ 18 июня 2020

На основании определения Transaction кажется, что вам нужен спецификатор / параметр времени жизни в самой структуре, а не в ссылке на параметр функции:

async fn tx_work(trans: &tokio_postgres::Transaction<'_>)

Это использует анонимное время жизни, но вы также можете явно указать параметр времени жизни:

async fn tx_work<'a>(trans: &tokio_postgres::Transaction<'a>)

Обычно эти времена жизни связывают с другими существующими временами жизни, например, если у вас уже было явное время жизни где-то еще, и это имеет смысл сделать это, вы можете передать его как параметр напрямую.

Это потому, что tokio_postgres::Transaction не полностью определяет тип больше, чем Vec (по сравнению с Vec<u8>), т.е. спецификаторы времени жизни являются частью имени типа, поэтому вам потребуется tokio_postgres::Transaction<'some_lifetime>, но, очевидно, вы также можете использовать анонимное время жизни '_.

Более конкретно, здесь параметр времени жизни Transaction относится на время жизни ссылок, содержащихся в структуре Transaction, тогда как время жизни ссылки на структуру Transaction (например, вы ini

Если это все еще сбивает с толку, я рекомендую вам прочитать прекрасную главу о жизнях из книги. Это неотъемлемая часть парадигмы программирования на Rust.

...