最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

rust - std::sync::OnceLock and once_cell::sync::Lazy don't return same type - Stack Overflow

programmeradmin1浏览0评论

I need to init once a variable.

So I do

static POOL: Lazy<Pool<AsyncMysqlConnection>> = Lazy::new(|| {
    let config = AsyncDieselConnectionManager::<diesel_async::AsyncMysqlConnection>::new(
       "mysql://[email protected]:3306/db",
    );
    Pool::builder(config).build().unwrap()
});

I get conn like

let mut conn = POOL.get().await?;

But I need some input (the url), so I change Lazy to OnceLock from std::sync

pub static POOL: OnceLock<Pool<AsyncMysqlConnection>> = OnceLock::new(); 

I write a fn to write into OnceLock

pub fn set_pool(db_url: &str) {
    let pool = AsyncDieselConnectionManager::<AsyncMysqlConnection>::new(db_url);
    let conn = Pool::builder(pool).build().unwrap();
    POOL.set(conn);
}

But when I want to get OnceLock value, I do the same thing as Lazy but get

the trait bound `deadpool::managed::Pool<AsyncDieselConnectionManager<AsyncMysqlConnection>>: DerefMut` is not satisfied                             --> src/diesel.rs:512:18                 |                                   512 | ...        .execute(&mut conn)        |             ^^^^^^^ unsatisfied trait bound                                   |                                       = help: the trait `DerefMut` is not implemented for `Pool<AsyncDieselConnectionManager<...>>`                           = help: the following other types implement trait `AsyncConnection`:                      AsyncMysqlConnection                    AsyncPgConnection                       SyncConnectionWrapper<C>      = note: required for `Pool<AsyncDieselConnectionManager<...>>` to implement `AsyncConnection`
    = note: the full name for the type has been written to '/data/data/com.termux/files/home/lucle/target/debug/deps/lucle-aa4e36718ce9a19c.long-type-4366048800889042929.txt'                              = note: consider using `--verbose` to print the full type name to the console 

I don't understand why I get this, seems the return type are the same between Lazy and OnceLock

I need to init once a variable.

So I do

static POOL: Lazy<Pool<AsyncMysqlConnection>> = Lazy::new(|| {
    let config = AsyncDieselConnectionManager::<diesel_async::AsyncMysqlConnection>::new(
       "mysql://[email protected]:3306/db",
    );
    Pool::builder(config).build().unwrap()
});

I get conn like

let mut conn = POOL.get().await?;

But I need some input (the url), so I change Lazy to OnceLock from std::sync

pub static POOL: OnceLock<Pool<AsyncMysqlConnection>> = OnceLock::new(); 

I write a fn to write into OnceLock

pub fn set_pool(db_url: &str) {
    let pool = AsyncDieselConnectionManager::<AsyncMysqlConnection>::new(db_url);
    let conn = Pool::builder(pool).build().unwrap();
    POOL.set(conn);
}

But when I want to get OnceLock value, I do the same thing as Lazy but get

the trait bound `deadpool::managed::Pool<AsyncDieselConnectionManager<AsyncMysqlConnection>>: DerefMut` is not satisfied                             --> src/diesel.rs:512:18                 |                                   512 | ...        .execute(&mut conn)        |             ^^^^^^^ unsatisfied trait bound                                   |                                       = help: the trait `DerefMut` is not implemented for `Pool<AsyncDieselConnectionManager<...>>`                           = help: the following other types implement trait `AsyncConnection`:                      AsyncMysqlConnection                    AsyncPgConnection                       SyncConnectionWrapper<C>      = note: required for `Pool<AsyncDieselConnectionManager<...>>` to implement `AsyncConnection`
    = note: the full name for the type has been written to '/data/data/com.termux/files/home/lucle/target/debug/deps/lucle-aa4e36718ce9a19c.long-type-4366048800889042929.txt'                              = note: consider using `--verbose` to print the full type name to the console 

I don't understand why I get this, seems the return type are the same between Lazy and OnceLock

Share Improve this question edited Mar 15 at 7:04 Shadow 34.3k10 gold badges65 silver badges75 bronze badges asked Mar 15 at 5:11 VanaVana 9384 gold badges15 silver badges24 bronze badges
Add a comment  | 

3 Answers 3

Reset to default 1
let mut conn = POOL.get().await?;

This is calling OnceLock::get() instead of Pool::get(), which returns an Option<&Pool>.

LazyLock Derefs to the value so it works, but OnceLock does not.

If you are certain the OnceLock has been initialized at this point, you can use POOL.get().unwrap().get().await. Alternatively and better, use OnceLock::get_or_init().

the problems seems to be a mutability issue; as your example code seems incomplete. you don't share the part of the code where the actual error happens:

 src/diesel.rs:512:18 | 512 | ...        .execute(&mut conn)

.execute(&mut conn) requires a mutable reference to conn. And POOL.get() returns a non-mutable reference. You need a mutable reference to conn.

here how to get mutable-reference to underlying data in a OnceLock https://stackoverflow/a/76695396/29977423

I fixed my issue with Mutex and OnceLock

发布评论

评论列表(0)

  1. 暂无评论