Immutable reference after mutable borrow

I've been reading about rust for the past week and (trying) to play around with it. It seems I run into similar problems related to ownership/borrowing every time I use it, so here is the simplest piece of code that sort of illustrates the usual problems.

After reading about RefCell I though it would work, and in fact compiles, but panicks at runtime. So my question is: how do I reference a vector while iterating over the same vector? Is there any better data structure to allow me to do this?

--

There is an example in the Rc documentation that uses Weak<T> that I guess would work here, but it's not stable yet.

Best How To :

Your program panics because you're trying to borrow the Vec mutably and immutably at the same time: this is not allowed.

What you need to do instead is wrap only the Strings in RefCell. This allows you to mutate the strings while iterating the Vec.

If you want to remove elements you can use retain(), which removes elements from the vector if the filter function return false: let mut vec = vec![1, 2, 3, 4]; vec.retain(|&x| x%2 == 0); assert_eq!(vec, [2, 4]); If you want to modify the elements in place there is map_in_place() but...

Your program panics because you're trying to borrow the Vec mutably and immutably at the same time: this is not allowed. What you need to do instead is wrap only the Strings in RefCell. This allows you to mutate the strings while iterating the Vec. use std::cell::RefCell; struct Res {...

You can run tests specifically for one module by providing it as an argument to the test binary. Cargo passes arguments to the test binary if you specify it after --, so something like this should work: cargo test -- module::you::want::to::test However, you can't compile only a part of a...

As you probably already know, types in Rust can be sized and unsized. Unsized types, as their name suggest, do not have a size required to store values of this type which is known to the compiler. For example, [u32] is an unsized array of u32s; because the number of...

You shouldn't be returning a pointer to a local stack variable at all. Doing so is undefined behaviour, and the compiler is completely free to do whatever it wants. When you say unsafe, you are promising the compiler that you will manually uphold all of its expected invariants... and then...

Indeed, the size of a [u8] isn't known at compile time. The size of &[u8] however is known at compile time because it's just a pointer plus a usize representing the length of sequence. format!("{:?}/{:?}", &bytes[0..2], &bytes[2..4]) Rust strings are encoded in utf-8, so working with strings in this way...

You simply have to specify T::Output as the return type of the function: fn divide<T: std::ops::Div>(a: T, b: T) -> T::Output { a / b } Edit to add more explanation on why you cannot do the cast inside the function When you are IN your generic function divide, the...

In your situation, you always want a maximum of 255 bytes, so you can use an array instead of a vector. This reduces the entire boilerplate to a mem::uninitialized() call, an as_mut_ptr() call and a slicing operation. unsafe { let mut v: [u16; 255] = mem::uninitialized(); let read_len = user32::GetWindowTextW(...

Is there a way that I could make this code update the board "in place"? There exists a type specially made for situations such as these. It's coincidentally called std::cell::Cell. You're allowed to mutate the contents of a Cell even when it has been immutably borrowed multiple times. Cell...

Your issue is a simple one: for i in values, where values is of type &Vec<u8>, iterates over references to each value; that is, i is of type &u8. Oring and adding and such with references doesn’t make sense; you need to dereference it, getting the underlying u8. The easiest...

Because macro_rules! is a bit dumber than you might expect. It does not, for example, bring imports with it when it expands something. It's best to think of macro expansion as mostly just a dumb copy+paste job. If you look at any reasonably well-written macro that depends on outside symbols,...

I know this has been answered before, but I can't find it... feel free to mark this as duplicate if you find it. The problem is that you are attempting to store a reference in a container that will outlive the reference. Here's a MCVE of your problem: fn main()...

To me it seems like let c = Bar::Fub(&17), the 17 lasts the same life time as the previous line where "Foo" is created on the stack A string literal always has 'static lifetime and will therefor always live long enough. I think the issue is that you are...

The problem with your code is that you have a coherence violation in it, and, very likely, any attempts to fix it would lead to new coherence violations. Coherence rules in Rust are somewhat complex, however, they are based on one principle: you can implement "your" traits for arbitrary types...

If you look at the documentation for Vec::dedup, you'll note that it's in a little section marked by the following: impl<T: PartialEq> Vec<T> This means that the methods below it exist only when the given constraints are satisfied. In this case, dedup isn't there because User doesn't implement the PartialEq...

Short answer The function fn2 receives a reference to a MyEnum1 as a parameter, but the Struct1 contains an owned MyEnum1. This means that you are actually trying to turn a reference into an owned value, which is only possible if you copy the data. Long answer Your code would...

Your resulting Vec needs to own the Strings, so remove the & before the user.reference.clone(). Playground URL: https://play.rust-lang.org/?gist=6a6b50ebf589fcce1dbf&version=nightly Gist URL: https://gist.github.com/6a6b50ebf589fcce1dbf...

You're looking for the following impl (spoiler: it doesn't exist): impl<A, B> ExactSizeIterator for Chain<A, B> where A: ExactSizeIterator, B: ExactSizeIterator { ... } An ExactSizeIterator must implement only one method, len(&self). So the idea behind an hypothetical implementation would be to sum both lengths so that chain_a_b.len() == a.len()...

See the crates.io documentation page on "Cargo and crates.io". To summarise: Nothing or a caret (^) means "at least this version, until the next incompatible version". A tilde (~) means "at least this version, until (but excluding) the next minor/major release". That is, ~1.2.3 will accept 1.2.X where X is...

Yes, if you want to write a singly-linked-list with a tail-pointer you have three choices: Safe and Mutable: Use NodePtr = Option<Rc<RefCell<Node<T>>>> Safe and Immutable: Use NodePtr = Option<Rc<Node<T>>> Unsafe and Mutable: Use tail: *mut Node<T> The *mut is going to be more efficient, and it's not like the Rc...

If you read the documentation for Result::unwrap, you'll note that it's under a little section called: impl<T, E: Debug> Result<T, E> This means the methods in that section only exist so long as the given constraints are satisfied. So far as I can see, the only reason unwrap wouldn't exist...

There are several problems with your code, I'll show you how to fix them one by one. The first problem is that you're using map() to iterate over an iterator. It won't work correctly because map() is lazy - unless you consume the iterator, the closure you passed to it...

Looks like I solved the problem. I turned the Python list into a C array, and passed that to the Rust function. Here is the working code: #[repr(C)] pub struct List_4 { // Create a struct using #[repr(C)], will do the same in Python so it is shareable array: [i32;...

Dashes in extern crate names can be replaced with underscores. So your example should be extern crate my_crate as my_crate1; Or if you want the underscored name, using the following will work extern crate my_crate; ...

It is not entirely correct to ask when Cell or RefCell should be used over Box and Rc because these types solve different problems. Indeed, more often than not RefCell is used together with Rc in order to provide mutability with shared ownership. So yes, use cases for Cell and...

An extern crate x; loads x into the current namespace. use statements are absolute paths unless they start with self::, so if you put your extern crate core; anywhere but the crate root then you need to specify an absolute path or use self::. mod foo { mod bar {...

While Haskell has two things to express such relationship between types, fundeps and associated types, Rust has only the latter. Traits in Rust can contain type members which are assigned with concrete values at the implementation site, and the compiler considers them uniquely identified by the combination of type parameters...

Putting aside "you should be using Result where possible," yes, this is basically how you catch a panic in Rust. Keep in mind that "recover" is perhaps not the best way of phrasing this in Rust. You don't really recover from panics in Rust, you isolate them, then detect them....

The string bound to "s" will be deallocated once the function ends ("s" goes out of scope), so you cannot return a reference to its contents outside the function. The best way is to return the string itself: fn read_shader_code(string_path: &str) -> String { let path = Path::new(string_path); let display...

It seems that the 2nd arg is being interpreted (either in rust or c) as sizeof string, rather than the value passed from the Rust code. Correct. You are experiencing undefined behavior here. Your C-Function has a different signature from the extern function you declared in Rust-Code. First of...

In the C++ code, you need to declare the Rust function (which is available via the C ABI) as extern "C". treble.h #include <stdint.h> extern "C" { int32_t treble(int32_t value); } The error you are getting is because the C++ compiler is name mangling the method treble before attempting to...

The problem is going to boil down to the fact that your shared libraries are not in the directories that your system expects them to be by default. There are a few tricks that you can use, 2 of which I was able to make work: Run R from the...

The error does look misleading, however, it is correct. Your problem in fact is that chunks() gives an iterator of slices into the original vector, and because you're trying to use this slice in a spawn()ed thread, it must have 'static lifetime, but naturally it does not. You said that...

Let's look at how std::mem::drop is implemented: pub fn drop<T>(_x: T) { } That's right: it's an empty function! That's because it takes advantage of move semantics to acquire ownership of its argument. If T implements Drop, the compiler automatically inserts a call to Drop::drop(_x) at the end of the...

On an iterator, the collect method can produce many types of collections: Vec, String and many more. You cannot call the method len() on a value of an unknown type. Specify the type with something like .collect::<Vec<_>>(). Or, when you’re purely wanting to find out how many items there are...

You don't. That implementation would be a bit useless, anyway. It would mean that all other error types would just be immediately boxed. At that point, you might as well just make use of the existing conversions involving Box<Error> and use that instead. If you want an error type that...

As for the title question - Yes, cyclic data structures can be handled without garbage collector. http://smallcultfollowing.com/babysteps/blog/2015/04/06/modeling-graphs-in-rust-using-vector-indices/ http://featherweightmusings.blogspot.com/2015/04/graphs-in-rust.html For first question. Yes, you can completely avoid garbage collector and manual deallocation in most cases. In some you rely on RC which is a simple form of garbage collection, or unsafe,...

Look at the definition of push_all: impl<T> Vec<T> where T: Clone { fn push_all(&mut self, other: &[T]); } Appends all elements in a slice to the Vec. Iterates over the slice other, clones each element, and then appends it to this Vec. The other vector is traversed in-order. (Emphasis mine.)...