I would like to use the Bellman-Ford algorithm from the petgraph crate. Here is a very simple sample program which does not compile:
extern crate petgraph;
use petgraph::prelude::*;
use petgraph::dot::{Dot, Config};
use petgraph::algo::bellman_ford;
fn main() {
println!("Hello, world!");
let mut deps = Graph::<&str, u64>::new();
let a = deps.add_node("later");
let b = deps.add_node("hello");
deps.update_edge(a, b, 5);
deps.update_edge(b, a, 10);
let result = bellman_ford(deps, NodeIndex::new(0));
}
When I compile this program I get this error message:
error[E0277]: the trait bound `petgraph::Graph<&str, f64>: petgraph::visit::IntoNodeIdentifiers` is not satisfied
--> src/main.rs:16:18
|
16 | let result = bellman_ford(deps, NodeIndex::new(0));
| ^^^^^^^^^^^^ the trait `petgraph::visit::IntoNodeIdentifiers` is not implemented for `petgraph::Graph<&str, f64>`
|
= help: the following implementations were found:
<&'a petgraph::Graph<N, E, Ty, Ix> as petgraph::visit::IntoNodeIdentifiers>
= note: required by `petgraph::algo::bellman_ford`
error[E0277]: the trait bound `petgraph::Graph<&str, f64>: petgraph::visit::IntoEdges` is not satisfied
--> src/main.rs:16:18
|
16 | let result = bellman_ford(deps, NodeIndex::new(0));
| ^^^^^^^^^^^^ the trait `petgraph::visit::IntoEdges` is not implemented for `petgraph::Graph<&str, f64>`
|
= help: the following implementations were found:
<&'a petgraph::Graph<N, E, Ty, Ix> as petgraph::visit::IntoEdges>
= note: required by `petgraph::algo::bellman_ford`
From what I have gathered, the implemented Bellman-Ford algorithm works with floats, not integers.
Using floats instead of the u64 and referencing deps later does the trick:
use petgraph::algo::bellman_ford;
fn main() {
let mut deps = Graph::<&str, f64>::new();
let a = deps.add_node("later");
let b = deps.add_node("hello");
deps.update_edge(a, b, 5.0);
deps.update_edge(b, a, 10.0);
let result = bellman_ford(&deps, NodeIndex::new(0));
println!("{:?}", result);
}
Related
I have a vector of a vector and need to concatenate the second one to the first (it's ok if the second one is dropped), i.e.
f([[1,2,3], [4,5,6]]) => [[1,2,3,4,5,6], []]
or
f([[1,2,3], [4,5,6]]) => [[1,2,3,4,5,6], [4,5,6]]
Both are okay.
My initial solution is:
fn problem() {
let mut items = Vec::new();
items.push(vec![1,2,3]);
items.push(vec![4,5,6]);
items[0].append(&mut items[1]);
}
But it has a compile time error due to 2 mutable borrows:
| items[0].append(&mut items[1]);
| ----- ------ ^^^^^ second mutable borrow occurs here
| | |
| | first borrow later used by call
| first mutable borrow occurs here
I could solve it with Box / Option, but I wonder whether there are better ways to solve this?
My solution with Box:
fn solution_with_box() {
let mut items = Vec::new();
items.push(Box::new(vec![1,2,3]));
items.push(Box::new(vec![4,5,6]));
let mut second = items[1].clone();
items[0].as_mut().append(second.as_mut());
}
My solution with Option:
fn solution_with_option() {
let mut items = vec::new();
items.push(some(vec![1,2,3]));
items.push(some(vec![4,5,6]));
let mut second = items[1].take();
items[0].as_mut().unwrap().append(second.as_mut().unwrap());
}
You can clone the data of items[1] as follows:
fn main() {
let mut items = Vec::new();
items.push(vec![1,2,3]);
items.push(vec![4,5,6]);
let mut a: Vec<i32> = items[1].clone();
&items[0].append(&mut a);
}
If you don't want to clone the data, you can use mem::take as suggested by #trentcl
fn main() {
let mut items = Vec::new();
items.push(vec![1,2,3]);
items.push(vec![4,5,6]);
let second = std::mem::take(&mut items[1]);
items[0].extend(second);
println!("{:?}", items);
}
This is not fastest way of doing it but it solves your problem.
fn problem() {
let mut items = Vec::new();
items.push(vec![1,2,3]);
items.push(vec![4,5,6]);
//we can not have two mutable references in the same scope
// items[0].append(&mut items[1]);
// instead you can flatten vector
let first = items.into_iter().flatten().collect(); // we consume items so its no longer available
let items = vec![first, vec![]];
println!("{:?}", items); // [[1,2,3,4,5,6], []]
}
You can use split_at_mut on a slice or vector to get mutable references to non-overlapping parts that can't interfere with each other, so that you can mutate the first inner vector and the second inner vector at the same time.
let mut items = Vec::new();
items.push(vec![1,2,3]);
items.push(vec![4,5,6]);
let (contains_first, contains_second) = items.split_at_mut(1);
contains_first[0].append(&mut contains_second[0]);
dbg!(items);
Rust Playground link
No copying or cloning occurs. Note that contains_second[0] corresponds to items[1] because the second slice split_at_mut returns starts indexing at wherever the split point is (here, 1).
you can solve the problem in two steps:
append the empty vector at the end
remove items[1] and append its elements to items[0]
fn problem() {
let mut items = Vec::new();
items.push(vec![1,2,3]);
items.push(vec![4,5,6]);
items.push(vec![0;0]);
let v = items.remove(1);
items[0].extend(v);
}
According to The Rust Programming Language, ch15-03, std::mem::drop takes an object, receives its ownership, and calls its drop function.
That's what this code does:
fn my_drop<T>(x: T) {}
fn main() {
let x = 5;
let y = &x;
let mut z = 4;
let v = vec![3, 4, 2, 5, 3, 5];
my_drop(v);
}
Is this what std::mem::drop does? Does it perform any other cleanup tasks other than these?
Let's take a look at the source:
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn drop<T>(_x: T) { }
#[inline] gives a hint to the compiler that the function should be inlined. #[stable] is used by the standard library to mark APIs that are available on the stable channel. Otherwise, it's really just an empty function! When _x goes out of scope as drop returns, its destructor is run; there is no other way to perform cleanup tasks implicitly in Rust.
I want to write a function that uses breadth-first search on a binary tree to print node values in order:
use std::collections::VecDeque;
use std::ops::Deref;
struct BinarySearchNode<'a> {
value: &'a str,
key: i32,
left: Option<Box<BinarySearchNode<'a>>>,
right: Option<Box<BinarySearchNode<'a>>>,
}
impl<'a> BinarySearchNode<'a> {
pub fn print(&self) -> String {
let mut queue = VecDeque::new();
let mut output = String::new();
queue.push_back(&self);
while let Some(ref current) = queue.pop_front() {
if let Some(left_node) = current.left {
queue.push_back(&left_node.deref());
}
if let Some(right_node) = current.right {
queue.push_back(&right_node.deref());
}
output = output + current.value + "\n";
}
output
}
}
fn main() {}
I get the error
error: borrowed value does not live long enough
--> src/main.rs:19:34
|
19 | queue.push_back(&left_node.deref());
| ^^^^^^^^^^^^^^^^^ does not live long enough
|
note: reference must be valid for the block suffix following statement 0 at 13:40...
--> src/main.rs:13:41
|
13 | let mut queue = VecDeque::new();
| ^
note: ...but borrowed value is only valid for the statement at 19:16
--> src/main.rs:19:17
|
19 | queue.push_back(&left_node.deref());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
help: consider using a `let` binding to increase its lifetime
--> src/main.rs:19:17
|
19 | queue.push_back(&left_node.deref());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: `left_node` does not live long enough
--> src/main.rs:19:34
|
19 | queue.push_back(&left_node.deref());
| ^^^^^^^^^
|
note: reference must be valid for the block suffix following statement 0 at 13:40...
--> src/main.rs:13:41
|
13 | let mut queue = VecDeque::new();
| ^
note: ...but borrowed value is only valid for the if let at 18:12
--> src/main.rs:18:13
|
18 | if let Some(left_node) = current.left {
| ^
error: borrowed value does not live long enough
--> src/main.rs:22:34
|
22 | queue.push_back(&right_node.deref());
| ^^^^^^^^^^^^^^^^^^ does not live long enough
|
note: reference must be valid for the block suffix following statement 0 at 13:40...
--> src/main.rs:13:41
|
13 | let mut queue = VecDeque::new();
| ^
note: ...but borrowed value is only valid for the statement at 22:16
--> src/main.rs:22:17
|
22 | queue.push_back(&right_node.deref());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
help: consider using a `let` binding to increase its lifetime
--> src/main.rs:22:17
|
22 | queue.push_back(&right_node.deref());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: `right_node` does not live long enough
--> src/main.rs:22:34
|
22 | queue.push_back(&right_node.deref());
| ^^^^^^^^^^
|
note: reference must be valid for the block suffix following statement 0 at 13:40...
--> src/main.rs:13:41
|
13 | let mut queue = VecDeque::new();
| ^
note: ...but borrowed value is only valid for the if let at 21:12
--> src/main.rs:21:13
|
21 | if let Some(right_node) = current.right {
| ^
error[E0507]: cannot move out of borrowed content
--> src/main.rs:18:38
|
18 | if let Some(left_node) = current.left {
| --------- ^^^^^^^ cannot move out of borrowed content
| |
| hint: to prevent move, use `ref left_node` or `ref mut left_node`
error[E0507]: cannot move out of borrowed content
--> src/main.rs:21:39
|
21 | if let Some(right_node) = current.right {
| ---------- ^^^^^^^ cannot move out of borrowed content
| |
| hint: to prevent move, use `ref right_node` or `ref mut right_node`
I needed to deref() because simply using the operator * was causing a type mismatch as it expected a reference and not a box. It seems those dereference slightly differently and at least in stable I can't destructure it either.
I get that this value is scoped within the while loop and doesn't live long enough to be in the VecDeque (if this is the right data structure for the job) but I'm not sure what the best way to go about extending that lifetime is or if there's simply a better way to write this entire thing as it feels a bit complex.
My main problem is that I'm not sure where to start refactoring this code and I surprisingly had a hard time finding examples of a breadth-first search performed on a binary tree in Rust to take patterns from.
Your main problem lies in this line (and the right version):
if let Some(left_node) = current.left
This tries to move the value contained in current.left into the pattern on the right side. the problem is that current.left is an Option<Box<BinarySearchNode<'a>>>. When you move the Box out of current, that would leave current without a valid value for left! Accessing that value in the future would lead to bad behavior.
Instead, you need to leave the value where it is and instead take a reference. The two main ways are to use the ref pattern modifier:
if let Some(ref left_node) = current.left
Or to call as_ref:
if let Some(left_node) = current.left.as_ref()
Here is complete code:
use std::collections::VecDeque;
struct BinarySearchNode<'a> {
value: &'a str,
key: i32,
left: Option<Box<BinarySearchNode<'a>>>,
right: Option<Box<BinarySearchNode<'a>>>,
}
impl<'a> BinarySearchNode<'a> {
pub fn print(&self) -> String {
let mut queue = VecDeque::new();
let mut output = String::new();
queue.push_back(self);
while let Some(current) = queue.pop_front() {
if let Some(left_node) = current.left.as_ref() {
queue.push_back(left_node);
}
if let Some(right_node) = current.right.as_ref() {
queue.push_back(right_node);
}
output = output + current.value + "\n";
}
output
}
}
fn main() {
let root = BinarySearchNode {
value: "a",
key: 0,
left: Some(Box::new(BinarySearchNode {
value: "b",
key: 1,
left: None,
right: None,
})),
right: Some(Box::new(BinarySearchNode {
value: "c",
key: 2,
left: None,
right: None,
})),
};
println!("{}", root.print());
}
Try this one:
pub fn print(&self) -> String {
let mut queue = VecDeque::new();
let mut output = String::new();
if let Some(ref left_node) = self.left {
queue.push_back(left_node);
}
if let Some(ref right_node) = self.right {
queue.push_back(right_node);
}
while let Some(ref current) = queue.pop_front() {
if let Some(ref left_node) = current.left {
queue.push_back(left_node);
}
if let Some(ref right_node) = current.right {
queue.push_back(right_node);
}
output = output + current.value + "\n";
}
output
}
I have enums that contain variables:
enum Asymmetric {
One(i32),
Two(i32, i32),
}
I want to change just one field of an already existing enum, without reassigning the entire enum. My code (playground):
// Does not compile
fn main() {
let two = Asymmetric::Two(4, 5);
let mut vec = vec![two];
foo(&mut vec[0]);
}
fn foo(baa: &mut Asymmetric) {
match baa {
&mut Asymmetric::Two(x0, x1) => {
x0 = 6;
}
_ => {}
}
}
This results in this error:
error[E0384]: re-assignment of immutable variable `x0`
--> src/main.rs:16:13
|
15 | &mut Asymmetric::Two(x0, x1) => {
| -- first assignment to `x0`
16 | x0 = 6;
| ^^^^^^ re-assignment of immutable variable
Thanks to "match ergonomics" (introduced in Rust 1.26, proposed here), you can write your code like this:
fn foo(baa: &mut Asymmetric) {
match baa {
Asymmetric::Two(x0, _) => {
*x0 = 6;
}
_ => {}
}
}
Since baa is a mutable reference, but your pattern you're matching against (Asymmetric::Two(x0, _)) is not, the name x0 is automatically bound as mutable reference.
You can also do it manually by using ref mut. See this working code (playground):
fn foo(baa: &mut Asymmetric) {
match *baa {
Asymmetric::Two(ref mut x0, _) => {
*x0 = 6;
}
_ => {}
}
}
Some minor changes that are not related to your error, but which increase your code quality:
usually you deref (with *) the matched-on value instead of adding & or &mut to every pattern in the match
you should use _ as a name placeholder if you don't need to bind to that name
In your case, you can simplify the code even further by using if let. Whenever you are only interested in one match-case, you should use if let instead:
fn foo(baa: &mut Asymmetric) {
if let Asymmetric::Two(x0, _) = baa {
*x0 = 6;
}
}
I'm coming from a C (and to a lesser extent, C++) background. I wrote the following code snippet:
fn main() {
let my_array = [1, 2, 3];
let print_me = |j| println!("= {}", j);
for k in my_array.iter() {
print_me(k);
}
}
This compiled and ran as expected, but then I specified the type of the argument passed to the closure print_me thus:
fn main() {
let my_array = [1, 2, 3];
let print_me = |j: i32| println!("= {}", j);
for k in my_array.iter() {
print_me(k);
}
}
I got a compilation error:
error[E0308]: mismatched types
--> src/main.rs:6:22
|
6 | print_me(k);
| ^
| |
| expected i32, found &{integer}
| help: consider dereferencing the borrow: `*k`
|
= note: expected type `i32`
found type `&{integer}`
Now this confused me until I changed k to &k in the for statement, which worked fine:
fn main() {
let my_array = [1, 2, 3];
let print_me = |j: i32| println!("= {}", j);
for &k in my_array.iter() {
print_me(k);
}
}
It seems that I misunderstood the for syntax itself -- or maybe the exact workings of an iterator -- or maybe the usage syntax of a reference vis-a-vis a pointer [which are related but distinct in C++].
In the construct for A in B { C1; C2; ... Cn }, what exactly are A and B supposed to be?
First of all, here's a link to the definition of for in the reference.
To summarise, B is any expression which evaluates to something that can be converted into a value that implements the Iterator<T> trait, whilst A is a irrefutable pattern that binds values of type T.
In your specific case, slice::iter returns an Iter<i32>, which implements Iterator<Item = &i32>. That is, it doesn't yield i32s, it yields &i32s.
Thus, in both the first and second examples, k is actually binding to &i32s, not i32s. When you specified the type of the closure, you were actually specifying the wrong type. The reason the final example works is because A is a pattern, not a variable name. What &k is actually doing is "de-structuring" the &i32, binding the i32 part to a variable named k.
The "irrefutable" part simply means that the pattern must always work. For example, you can't do for Some(x) in thingy where thingy implements Iterator<Option<_>>; Some(x) would not necessarily be valid for every element in the iterator; thus, it's a refutable pattern.
Many iterators actually return a reference rather than a value. To be sure, you have to check the return type of .iter(), which should be of the form Iterator<Item = X>: X will be the type of the variable returned.
So here:
fn main() {
let my_array = [1, 2, 3];
let print_me = |j: i32| println!("= {}", j);
for k in my_array.iter() {
print_me(k);
}
}
This X is &i32 (a reference to i32), and therefore k has type &i32.
This is why, when calling print_me, there is an error: &i32 is passed where i32 is expected.
There are multiple possible fixes here:
specify a different type to print_me:
let print_me = |j: &i32| println!("= {}", j);
dereference the value of k:
print_me(*k);
change the type of k by destructuring in the loop:
for &k in my_array.iter() { ... }
The destructuring occurs because for .. in accepts an irrefutable pattern, so you can pattern match like you would do in a match expression, except that the variable's type has to match (otherwise you get a compiler time error).
To better illustrate it, we can use a slightly more complicated example:
fn main() {
let my_array = [(1, 2), (2, 3), (3, 4)];
let print_me = |a: i32, b: i32| println!("= {} {}", a, b);
for &(j, k) in my_array.iter() {
print_me(j, k)
}
}
The type of my_array is [(i32, i32)]: an array of tuples of 2 i32. The result of .iter() is therefore of type Iterator<Item = &(i32, i32)>: an iterator to a reference to a tuple of 2 i32 aka &(i32, i32).
When we use the irrefutable pattern &(j, k) what happens is that we destructure the tuple so that:
the first element binds to j (inferred to be of type i32, only works because i32 is Copy)
the second element binds to k ((inferred to be of type i32)
j and k thus become temporary copies of the i32 inside this element.