'Temporary value created when unwrap()

I'm trying to create a thread-safe version of a stack based on a vector.

The unsafe version (just a simplified example to focus in) is

fn top<'a, T>( v: &'a Vec<T> ) ->  &'a T {

    return  & v[0];
} // ()

// --------------------------------------------
fn main() {

    let mut v = Vec::<i32>::new();

    v.push( 1234 );

    println!( "{}", top( & v ) );
} // ()

But the safe version does not compile:

type SafeVec<T> = Arc< RwLock< Vec<T> > >;

// --------------------------------------------
fn new_safe_vec<T>() -> SafeVec<T> {

    return Arc::new( RwLock::new(  Vec::<T>::new() ) );
} // ()

// --------------------------------------------
fn top_safe<'a, T>( v: &'a SafeVec<T> ) ->  &'a T {

    return  & v.read().unwrap()[0]; <------     returns a value referencing
                                    <------     data owned by the current function
                                    <------     (temporary crated here)
} // ()

// --------------------------------------------
fn main() {
    
} // ()

Does unwrap() create a temporary copy of the vector held inside? How to avoid it?



Solution 1:[1]

And, just for completeness, to avoid a copy we'll need to have a guarded reference to the cell. A trick could be using a macro so that the RwLockReadGuard is kept in main().

use std::sync::Arc;
use std::sync::RwLock;

// ==================================================================

type SafeVec<T> = Arc< RwLock< Vec<T> > >;

// ------------------------------------------------------------------
fn new_safe_vec<T>() -> SafeVec<T> {
    return Arc::new( RwLock::new(  Vec::<T>::new() ) );
} // ()


// ------------------------------------------------------------------
macro_rules! top_safe {
    ($v: expr) => {
        $v.read().unwrap()[0]
    } // ()
} // macro

// ==================================================================
fn main() {

    let sv = new_safe_vec::<i32>();

    sv.write().unwrap().push( 1234 );

    println!( "{}", top_safe!( & sv ) );

} // ()

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 cibercitizen1