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?










share|improve this question

























    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?










    share|improve this question























      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?










      share|improve this question













      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






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked 19 hours ago









      hellow

      3,59811941




      3,59811941






















          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.



          1. Instead of RwLock<Vec<NotCloneable>> you could use RwLock<Option<Vec<NotCloneable>>> and then use Option::take() to get the value the RwLock was holding and leaving None


          2. You could use std::mem::replace() to get the vec 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)






          share|improve this answer






















          • 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










          Your Answer






          StackExchange.ifUsing("editor", function ()
          StackExchange.using("externalEditor", function ()
          StackExchange.using("snippets", function ()
          StackExchange.snippets.init();
          );
          );
          , "code-snippets");

          StackExchange.ready(function()
          var channelOptions =
          tags: "".split(" "),
          id: "1"
          ;
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function()
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled)
          StackExchange.using("snippets", function()
          createEditor();
          );

          else
          createEditor();

          );

          function createEditor()
          StackExchange.prepareEditor(
          heartbeatType: 'answer',
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader:
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          ,
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          );



          );













           

          draft saved


          draft discarded


















          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






























          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.



          1. Instead of RwLock<Vec<NotCloneable>> you could use RwLock<Option<Vec<NotCloneable>>> and then use Option::take() to get the value the RwLock was holding and leaving None


          2. You could use std::mem::replace() to get the vec 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)






          share|improve this answer






















          • 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














          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.



          1. Instead of RwLock<Vec<NotCloneable>> you could use RwLock<Option<Vec<NotCloneable>>> and then use Option::take() to get the value the RwLock was holding and leaving None


          2. You could use std::mem::replace() to get the vec 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)






          share|improve this answer






















          • 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












          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.



          1. Instead of RwLock<Vec<NotCloneable>> you could use RwLock<Option<Vec<NotCloneable>>> and then use Option::take() to get the value the RwLock was holding and leaving None


          2. You could use std::mem::replace() to get the vec 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)






          share|improve this answer














          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.



          1. Instead of RwLock<Vec<NotCloneable>> you could use RwLock<Option<Vec<NotCloneable>>> and then use Option::take() to get the value the RwLock was holding and leaving None


          2. You could use std::mem::replace() to get the vec 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)







          share|improve this answer














          share|improve this answer



          share|improve this answer








          answered 19 hours ago


























          community wiki





          hellow












          • 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
















          • 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















          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

















           

          draft saved


          draft discarded















































           


          draft saved


          draft discarded














          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














































































          這個網誌中的熱門文章

          How to read a connectionString WITH PROVIDER in .NET Core?

          Node.js Script on GitHub Pages or Amazon S3

          Museum of Modern and Contemporary Art of Trento and Rovereto