borrow-checker

Lifetimes for method returning iterator of structs with same lifetime

喜欢而已 提交于 2019-12-18 09:00:20
问题 Assume the following contrived example: struct Board { squares: Vec<i32>, } struct Point<'a> { board: &'a Board, x: i32, y: i32, } impl<'a> Point<'a> { pub fn neighbors(&self) -> impl Iterator<Item = Point<'a>> { [(0, -1), (-1, 0), (1, 0), (1, 0)] .iter().map(|(dx, dy)| Point { board: self.board, x: self.x + dx, y: self.y + dy, }) } } This doesn't compile because from what I understand the lifetime of the points created in the lambda isn't correct: error[E0495]: cannot infer an appropriate

Pushing something into a vector depending on its last element

跟風遠走 提交于 2019-12-18 08:09:09
问题 I would like to get the last element of a vector and use it to determine the next element to push in. Here's an example how it doesn't work, but it shows what I'm trying to achieve: let mut vector: Vec<i32> = Vec::new(); if let Some(last_value) = vector.last() { vector.push(*last_value + 1); } I can't use push while the vector is also borrowed immutably: error[E0502]: cannot borrow `vector` as mutable because it is also borrowed as immutable --> src/main.rs:5:9 | 4 | if let Some(last_value) =

Manipulating an object from inside a loop that borrows it

♀尐吖头ヾ 提交于 2019-12-18 07:30:45
问题 I'm writing some code in Rust that connects to a remote server, and depending on the messages sent by that server, computes some statistics or executes actions based on these statistics. But this is more of a learning project for me and I've run into an issue. Here is the code that I have reduced to a bare minimum to reproduce the problem : // Repro code for error[E0502]: cannot borrow `*self` as mutable because `self.server` is also borrowed as immutable use std::collections::HashMap; struct

What's the correct way to implement the equivalent of multiple mutable (statically allocated, statically dispatched, etc.) callbacks in Rust?

穿精又带淫゛_ 提交于 2019-12-17 21:15:14
问题 I have the following example code, which is the standard basis of event-driven APIs in other programming languages, but in Rust the borrow checker blocks it with "cannot borrow p1 as mutable more than once at a time": struct Pen { color_cmyk: u32, ink: usize, } impl Pen { pub fn new() -> Pen { Pen { color_cmyk: 0x80800000, ink: 20000, } } pub fn write(&mut self, text: &str) -> bool { if self.ink < text.len() { return false; } self.ink -= text.len(); true } } fn main() { println!("Hello, world

Why does the usage of by_ref().take() differ between the Iterator and Read traits?

耗尽温柔 提交于 2019-12-17 20:06:23
问题 Here are two functions: fn foo<I>(iter: &mut I) where I: std::iter::Iterator<Item = u8>, { let x = iter.by_ref(); let y = x.take(2); } fn bar<I>(iter: &mut I) where I: std::io::Read, { let x = iter.by_ref(); let y = x.take(2); } While the first compiles fine, the second gives the compilation error: error[E0507]: cannot move out of borrowed content --> src/lib.rs:14:13 | 14 | let y = x.take(2); | ^ cannot move out of borrowed content The signatures of by_ref and take are almost identical in

How do I add references to a container when the borrowed values are created after the container?

假装没事ソ 提交于 2019-12-17 16:56:10
问题 For reasons related to code organization, I need the compiler to accept the following (simplified) code: fn f() { let mut vec = Vec::new(); let a = 0; vec.push(&a); let b = 0; vec.push(&b); // Use `vec` } The compiler complains error: `a` does not live long enough --> src/main.rs:8:1 | 4 | vec.push(&a); | - borrow occurs here ... 8 | } | ^ `a` dropped here while still borrowed | = note: values in a scope are dropped in the opposite order they are created error: `b` does not live long enough -

Borrow checker and function arguments in Rust, correct or over zealous? [duplicate]

社会主义新天地 提交于 2019-12-17 14:24:26
问题 This question already has an answer here : Cannot borrow as immutable because it is also borrowed as mutable in function arguments (1 answer) Closed last year . When a mutable argument is passed as a function argument, the borrow checker doesn't allow this to be used to construct other arguments, even when those arguments clone values without holding a reference. While assigning variables outside the function is always an option 1 , logically this seems over zealous and something the borrow

Borrow checker and function arguments in Rust, correct or over zealous? [duplicate]

青春壹個敷衍的年華 提交于 2019-12-17 14:23:28
问题 This question already has an answer here : Cannot borrow as immutable because it is also borrowed as mutable in function arguments (1 answer) Closed last year . When a mutable argument is passed as a function argument, the borrow checker doesn't allow this to be used to construct other arguments, even when those arguments clone values without holding a reference. While assigning variables outside the function is always an option 1 , logically this seems over zealous and something the borrow

Can't borrow File from &mut self (error msg: cannot move out of borrowed content)

允我心安 提交于 2019-12-17 12:15:11
问题 use std::fs::File; use std::io::Read; pub struct Foo { maybe_file: Option<File>, } impl Foo { pub fn init(&mut self) { self.maybe_file = Some(File::open("/proc/uptime").unwrap()); } pub fn print(&mut self) { let mut file = self.maybe_file.unwrap(); let mut s = String::new(); file.read_to_string(&mut s).unwrap(); println!("Uptime: {}", s); } } fn main() {} Compiling this will give me: error[E0507]: cannot move out of borrowed content --> src/main.rs:14:24 | 14 | let mut file = self.maybe_file

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

删除回忆录丶 提交于 2019-12-17 06:57:05
问题 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)