borrow-checker

How do I move out of a struct field that is an Option?

折月煮酒 提交于 2019-11-27 09:45:35
I want to collect changes to a struct and apply them all at once. The basic outline looks like this: enum SomeEnum { Foo, Bar, } struct SomeStruct { attrib: SomeEnum, next_attrib: Option<SomeEnum>, } impl SomeStruct { pub fn apply_changes(&mut self) { if let Some(se) = self.next_attrib { self.attrib = se; } self.next_attrib = None; } } which yields the following compiler error: error[E0507]: cannot move out of borrowed content --> src/lib.rs:13:27 | 13 | if let Some(se) = self.next_attrib { | -- ^^^^ cannot move out of borrowed content | | | hint: to prevent move, use `ref se` or `ref mut se`

“borrowed value does not live long enough” when using as_slice()

て烟熏妆下的殇ゞ 提交于 2019-11-27 07:45:51
问题 I ran into an error: extern crate rustc_serialize; // 0.3.24 use rustc_serialize::base64::{self, FromBase64, ToBase64}; fn main() { let a: [u8; 30] = [0; 30]; let b = a.from_base64().unwrap().as_slice(); println!("{:?}", b); } The error: error[E0597]: borrowed value does not live long enough --> src/main.rs:7:13 | 7 | let b = a.from_base64().unwrap().as_slice(); | ^^^^^^^^^^^^^^^^^^^^^^^^ - temporary value dropped here while still borrowed | | | temporary value does not live long enough 8 |

How to use a struct's member as its own key when inserting the struct into a map without duplicating it?

梦想与她 提交于 2019-11-27 06:17:21
问题 Is it possible to insert a struct into a map where the key is owned by the value being inserted? When using hash-maps in C, this is something which I'm used to doing. Pseudocode example: struct MyStruct { pub map: BTreeMap<&String, StructThatContainsString>, // XXX ^ Rust wants lifetime specified here! } struct StructThatContainsString { id: String, other_data: u32, } fn my_fn() { let ms = MyStruct { map: BTreeMap::new() }; let item = StructThatContainsString { id: "Some Key".to_string(),

Double mutable borrow error in a loop happens even with NLL on

百般思念 提交于 2019-11-27 05:35:19
Suppose I have several structures like in the following example, and in the next() method I need to pull the next event using a user-provided buffer, but if this event is a comment, and ignore comments flag is set to true, I need to pull the next event again: struct Parser { ignore_comments: bool, } enum XmlEvent<'buf> { Comment(&'buf str), Other(&'buf str), } impl Parser { fn next<'buf>(&mut self, buffer: &'buf mut String) -> XmlEvent<'buf> { let result = loop { buffer.clear(); let temp_event = self.parse_outside_tag(buffer); match temp_event { XmlEvent::Comment(_) if self.ignore_comments =>

How can I mutate other elements of a HashMap when using the entry pattern?

a 夏天 提交于 2019-11-27 02:24:56
I'd like to use a HashMap to cache an expensive computation that's dependent on other entries in the map. The entry pattern only provides a mutable reference to the matched value, but not to the rest of the HashMap . I'd really appreciate feedback on a better way to solve this (incorrect) toy example: use std::collections::HashMap; use std::collections::hash_map::Entry::{Occupied, Vacant}; fn compute(cache: &mut HashMap<u32, u32>, input: u32) -> u32 { match cache.entry(input) { Vacant(entry) => if input > 2 { // Trivial placeholder for an expensive computation. *entry.insert(compute(&mut cache

“borrowed value does not live long enough” when using the builder pattern

妖精的绣舞 提交于 2019-11-27 02:21:59
I have the following code: pub struct Canvas<'a> { width: isize, height: isize, color: Color, surface: Surface, texture: Texture, renderer: &'a Renderer, } impl<'a> Canvas<'a> { pub fn new(width: isize, height: isize, renderer: &'a Renderer) -> Canvas<'a> { let color = Color::RGB(0, 30, 0); let mut surface = core::create_surface(width, height); let texture = Canvas::gen_texture(&mut surface, width, height, color, renderer); Canvas { width: width, height: height, color: color, surface: surface, texture: texture, renderer: renderer, } } pub fn color(&mut self, color: Color) -> &mut Canvas<'a> {

Iterating over a vector of mutable references to trait objects

被刻印的时光 ゝ 提交于 2019-11-26 23:30:03
问题 I have a struct that holds mutable references to trait objects: trait Task { fn do_it(&mut self); } struct Worker<'a> { tasks: Vec<&'a mut Task>, } In a method of Worker , I want to iterate over the tasks and call their do_it : impl<'a> Worker<'a> { pub fn work(&mut self) { for task in self.tasks.iter() { self.work_one(*task); } } fn work_one(&self, task: &mut Task) { task.do_it(); } } Sadly, the borrow checker does not let me do it: error[E0389]: cannot borrow data mutably in a `&` reference

How to update-or-insert on a Vec?

不想你离开。 提交于 2019-11-26 23:16:27
I'm writing a data structure in Rust. It contains a Vec of key-value pairs. When inserting into the structure, I need to find a matching key and update both the key and the value (which is actually a child pointer). The code looks a bit like this, where pivots is a ref mut to Vec<Pivot> and Pivot is just a struct with two fields: match pivots.iter_mut().find(|ref p| key <= p.min_key) { // first mutable borrow Some(ref mut pivot) => { // If there is one, insert into it and update the pivot key pivot.min_key = key; pivot.child.insert(key, value) // recursive call }, // o/w, insert a new leaf at

Why can't I reuse a &mut reference after passing it to a function that accepts a generic type?

醉酒当歌 提交于 2019-11-26 21:50:20
问题 Why doesn't this code compile: fn use_cursor(cursor: &mut io::Cursor<&mut Vec<u8>>) { // do some work } fn take_reference(data: &mut Vec<u8>) { { let mut buf = io::Cursor::new(data); use_cursor(&mut buf); } data.len(); } fn produce_data() { let mut data = Vec::new(); take_reference(&mut data); data.len(); } The error in this case is: error[E0382]: use of moved value: `*data` --> src/main.rs:14:5 | 9 | let mut buf = io::Cursor::new(data); | ---- value moved here ... 14 | data.len(); | ^^^^

Temporarily move out of borrowed content

醉酒当歌 提交于 2019-11-26 19:12:05
I'm tring to replace a value in a mutable borrow; moving part of it into the new value: enum Foo<T> { Bar(T), Baz(T), } impl<T> Foo<T> { fn switch(&mut self) { *self = match self { &mut Foo::Bar(val) => Foo::Baz(val), &mut Foo::Baz(val) => Foo::Bar(val), } } } The code above doesn't work, and understandibly so, moving the value out of self breaks the integrity of it. But since that value is dropped immediately afterwards, I (if not the compiler) could guarantee it's safety. Is there some way to achieve this? I feel like this is a job for unsafe code, but I'm not sure how that would work.