Replace the content of an RwLockWriteGuard
up vote
2
down vote
favorite
Let's assume the following code:
use std::sync::RwLock;
pub struct NotCloneable(u8);
pub struct Foo
value: RwLock<Vec<NotCloneable>>,
impl Foo
// does not work
pub fn filter_out_values(&self)
let mut guard = self.value.write().unwrap();
*guard = guard.into_iter().filter(
error[E0507]: cannot move out of borrowed content
--> src/lib.rs:12:18
|
12 | *guard = guard.into_iter().filter(|nc| nc.0 != 0).collect();
| ^^^^^ cannot move out of borrowed content
(playground)
How do I make the function filter_out_values
work?
rust
add a comment |
up vote
2
down vote
favorite
Let's assume the following code:
use std::sync::RwLock;
pub struct NotCloneable(u8);
pub struct Foo
value: RwLock<Vec<NotCloneable>>,
impl Foo
// does not work
pub fn filter_out_values(&self)
let mut guard = self.value.write().unwrap();
*guard = guard.into_iter().filter(
error[E0507]: cannot move out of borrowed content
--> src/lib.rs:12:18
|
12 | *guard = guard.into_iter().filter(|nc| nc.0 != 0).collect();
| ^^^^^ cannot move out of borrowed content
(playground)
How do I make the function filter_out_values
work?
rust
add a comment |
up vote
2
down vote
favorite
up vote
2
down vote
favorite
Let's assume the following code:
use std::sync::RwLock;
pub struct NotCloneable(u8);
pub struct Foo
value: RwLock<Vec<NotCloneable>>,
impl Foo
// does not work
pub fn filter_out_values(&self)
let mut guard = self.value.write().unwrap();
*guard = guard.into_iter().filter(
error[E0507]: cannot move out of borrowed content
--> src/lib.rs:12:18
|
12 | *guard = guard.into_iter().filter(|nc| nc.0 != 0).collect();
| ^^^^^ cannot move out of borrowed content
(playground)
How do I make the function filter_out_values
work?
rust
Let's assume the following code:
use std::sync::RwLock;
pub struct NotCloneable(u8);
pub struct Foo
value: RwLock<Vec<NotCloneable>>,
impl Foo
// does not work
pub fn filter_out_values(&self)
let mut guard = self.value.write().unwrap();
*guard = guard.into_iter().filter(
error[E0507]: cannot move out of borrowed content
--> src/lib.rs:12:18
|
12 | *guard = guard.into_iter().filter(|nc| nc.0 != 0).collect();
| ^^^^^ cannot move out of borrowed content
(playground)
How do I make the function filter_out_values
work?
rust
rust
asked 19 hours ago
hellow
3,59811941
3,59811941
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
up vote
3
down vote
The special circumstance here is, that your T
is not Cloneable, therefore you cannot use guard.iter().filter(...).cloned().collect()
.
I see two options here.
Instead of
RwLock<Vec<NotCloneable>>
you could useRwLock<Option<Vec<NotCloneable>>>
and then useOption::take()
to get the value theRwLock
was holding and leavingNone
You could use
std::mem::replace()
to get thevec
from the guard without triggering the error, because there is no way that you leave the value of the RwLock in an undefined state, where it does not hold any value
use std::sync::RwLock;
pub struct NotCloneable(u8);
pub struct Foo
value: RwLock<Vec<NotCloneable>>,
impl Foo
pub fn filter_out_values(&self)
let mut guard = self.value.write().unwrap();
let vec = std::mem::replace(&mut *guard, vec!);
*guard = vec.into_iter().filter(
pub struct Foo1
value: RwLock<Option<Vec<NotCloneable>>>,
impl Foo1
pub fn filter_out_values(&self) nc.0 != 0).collect());
(playground)
I think this answer could be improved by laying down guidelines for when to use either alternatives: usereplace
if you can andOption<_>
if you must. With the difference being that when theT
inRwLock<T>
can be cheaply built (like an emptyVec
), then is better for ease of use to avoid the superfluous layer of wrapping, but otherwise a slightly more awkward ease of use might be worth the performance gain.
– Matthieu M.
13 hours ago
It's a community answer, feel free to add stuff
– hellow
13 hours ago
add a comment |
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
3
down vote
The special circumstance here is, that your T
is not Cloneable, therefore you cannot use guard.iter().filter(...).cloned().collect()
.
I see two options here.
Instead of
RwLock<Vec<NotCloneable>>
you could useRwLock<Option<Vec<NotCloneable>>>
and then useOption::take()
to get the value theRwLock
was holding and leavingNone
You could use
std::mem::replace()
to get thevec
from the guard without triggering the error, because there is no way that you leave the value of the RwLock in an undefined state, where it does not hold any value
use std::sync::RwLock;
pub struct NotCloneable(u8);
pub struct Foo
value: RwLock<Vec<NotCloneable>>,
impl Foo
pub fn filter_out_values(&self)
let mut guard = self.value.write().unwrap();
let vec = std::mem::replace(&mut *guard, vec!);
*guard = vec.into_iter().filter(
pub struct Foo1
value: RwLock<Option<Vec<NotCloneable>>>,
impl Foo1
pub fn filter_out_values(&self) nc.0 != 0).collect());
(playground)
I think this answer could be improved by laying down guidelines for when to use either alternatives: usereplace
if you can andOption<_>
if you must. With the difference being that when theT
inRwLock<T>
can be cheaply built (like an emptyVec
), then is better for ease of use to avoid the superfluous layer of wrapping, but otherwise a slightly more awkward ease of use might be worth the performance gain.
– Matthieu M.
13 hours ago
It's a community answer, feel free to add stuff
– hellow
13 hours ago
add a comment |
up vote
3
down vote
The special circumstance here is, that your T
is not Cloneable, therefore you cannot use guard.iter().filter(...).cloned().collect()
.
I see two options here.
Instead of
RwLock<Vec<NotCloneable>>
you could useRwLock<Option<Vec<NotCloneable>>>
and then useOption::take()
to get the value theRwLock
was holding and leavingNone
You could use
std::mem::replace()
to get thevec
from the guard without triggering the error, because there is no way that you leave the value of the RwLock in an undefined state, where it does not hold any value
use std::sync::RwLock;
pub struct NotCloneable(u8);
pub struct Foo
value: RwLock<Vec<NotCloneable>>,
impl Foo
pub fn filter_out_values(&self)
let mut guard = self.value.write().unwrap();
let vec = std::mem::replace(&mut *guard, vec!);
*guard = vec.into_iter().filter(
pub struct Foo1
value: RwLock<Option<Vec<NotCloneable>>>,
impl Foo1
pub fn filter_out_values(&self) nc.0 != 0).collect());
(playground)
I think this answer could be improved by laying down guidelines for when to use either alternatives: usereplace
if you can andOption<_>
if you must. With the difference being that when theT
inRwLock<T>
can be cheaply built (like an emptyVec
), then is better for ease of use to avoid the superfluous layer of wrapping, but otherwise a slightly more awkward ease of use might be worth the performance gain.
– Matthieu M.
13 hours ago
It's a community answer, feel free to add stuff
– hellow
13 hours ago
add a comment |
up vote
3
down vote
up vote
3
down vote
The special circumstance here is, that your T
is not Cloneable, therefore you cannot use guard.iter().filter(...).cloned().collect()
.
I see two options here.
Instead of
RwLock<Vec<NotCloneable>>
you could useRwLock<Option<Vec<NotCloneable>>>
and then useOption::take()
to get the value theRwLock
was holding and leavingNone
You could use
std::mem::replace()
to get thevec
from the guard without triggering the error, because there is no way that you leave the value of the RwLock in an undefined state, where it does not hold any value
use std::sync::RwLock;
pub struct NotCloneable(u8);
pub struct Foo
value: RwLock<Vec<NotCloneable>>,
impl Foo
pub fn filter_out_values(&self)
let mut guard = self.value.write().unwrap();
let vec = std::mem::replace(&mut *guard, vec!);
*guard = vec.into_iter().filter(
pub struct Foo1
value: RwLock<Option<Vec<NotCloneable>>>,
impl Foo1
pub fn filter_out_values(&self) nc.0 != 0).collect());
(playground)
The special circumstance here is, that your T
is not Cloneable, therefore you cannot use guard.iter().filter(...).cloned().collect()
.
I see two options here.
Instead of
RwLock<Vec<NotCloneable>>
you could useRwLock<Option<Vec<NotCloneable>>>
and then useOption::take()
to get the value theRwLock
was holding and leavingNone
You could use
std::mem::replace()
to get thevec
from the guard without triggering the error, because there is no way that you leave the value of the RwLock in an undefined state, where it does not hold any value
use std::sync::RwLock;
pub struct NotCloneable(u8);
pub struct Foo
value: RwLock<Vec<NotCloneable>>,
impl Foo
pub fn filter_out_values(&self)
let mut guard = self.value.write().unwrap();
let vec = std::mem::replace(&mut *guard, vec!);
*guard = vec.into_iter().filter(
pub struct Foo1
value: RwLock<Option<Vec<NotCloneable>>>,
impl Foo1
pub fn filter_out_values(&self) nc.0 != 0).collect());
(playground)
answered 19 hours ago
community wiki
hellow
I think this answer could be improved by laying down guidelines for when to use either alternatives: usereplace
if you can andOption<_>
if you must. With the difference being that when theT
inRwLock<T>
can be cheaply built (like an emptyVec
), then is better for ease of use to avoid the superfluous layer of wrapping, but otherwise a slightly more awkward ease of use might be worth the performance gain.
– Matthieu M.
13 hours ago
It's a community answer, feel free to add stuff
– hellow
13 hours ago
add a comment |
I think this answer could be improved by laying down guidelines for when to use either alternatives: usereplace
if you can andOption<_>
if you must. With the difference being that when theT
inRwLock<T>
can be cheaply built (like an emptyVec
), then is better for ease of use to avoid the superfluous layer of wrapping, but otherwise a slightly more awkward ease of use might be worth the performance gain.
– Matthieu M.
13 hours ago
It's a community answer, feel free to add stuff
– hellow
13 hours ago
I think this answer could be improved by laying down guidelines for when to use either alternatives: use
replace
if you can and Option<_>
if you must. With the difference being that when the T
in RwLock<T>
can be cheaply built (like an empty Vec
), then is better for ease of use to avoid the superfluous layer of wrapping, but otherwise a slightly more awkward ease of use might be worth the performance gain.– Matthieu M.
13 hours ago
I think this answer could be improved by laying down guidelines for when to use either alternatives: use
replace
if you can and Option<_>
if you must. With the difference being that when the T
in RwLock<T>
can be cheaply built (like an empty Vec
), then is better for ease of use to avoid the superfluous layer of wrapping, but otherwise a slightly more awkward ease of use might be worth the performance gain.– Matthieu M.
13 hours ago
It's a community answer, feel free to add stuff
– hellow
13 hours ago
It's a community answer, feel free to add stuff
– hellow
13 hours ago
add a comment |
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53237152%2freplace-the-content-of-an-rwlockwriteguard%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password