简体   繁体   中英

Thread local RefCell as replacement to local variable in Rust

I'm new to Rust. I'm trying to implement alternative to private variable inside classes to keep Postgres connection inside Struct. Currently I have:

    thread_local! {

        static CONNECTION: RefCell<Option<Connection>> = RefCell::new(None);
    }

Than I initialize it like this:

        PostgresDb::CONNECTION.with(|pg_connection| {
            *pg_connection.borrow_mut() = Some(connection)
        });

It works fine. But when I try to execute some query on it like this:

PostgresDb::CONNECTION.with(|pg_connection| {
            *pg_connection.borrow_mut().map(|conn| conn.execute("Select * from test", &[]));
}

I'm getting:

type `std::option::Option<Result<u64, psql::Error>>` cannot be dereferenced

If I change it to:

PostgresDb::CONNECTION.with(|pg_connection| {
            pg_connection.borrow_mut().map(|conn| conn.execute("Select * from test", &[]));

I'm getting:

cannot move out of dereference of `RefMut<'_, std::option::Option<psql::Connection>>`
move occurs because value has type `std::option::Option<psql::Connection>`, which does not implement the `Copy` trait

What should I change to make it work?

The problem is that Option::map() consumes the option in order to pass the closure it receives the content of the option. Since conn.execute only needs a (mutable) reference to the option contents, you can create a new Option whose content references the contents of the original one, and pass that to map() . This is easiest to accomplish with the Option::as_mut() convenience method:

pg_connection.borrow_mut().as_mut().map(|conn| conn.execute(...));

In most cases the error "cannot move out of... Option " can be resolved with the use of Option::as_ref or Option::as_mut .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM