How to compare two pointers? - rust

I want to compare two pointers within this loop:
#[derive(Debug)]
struct Test {
first: i32,
second: i32
}
fn main() {
let test = vec![Test {first: 1, second: 2}, Test {first: 3, second: 4}, Test {first: 5, second: 6}];
for item in test.iter() {
println!("--- {:?}", item);
println!("item {:p}", item);
println!("test.last().unwrap() {:p}", test.last().unwrap());
// if item == test.last().unwrap() {
// println!("Last item!");
// }
}
}
The println gives me the same addresses:
--- Test { first: 1, second: 2 }
item 0x563caaf3bb40
test.last().unwrap() 0x563caaf3bb50
--- Test { first: 3, second: 4 }
item 0x563caaf3bb48
test.last().unwrap() 0x563caaf3bb50
--- Test { first: 5, second: 6 }
item 0x563caaf3bb50
test.last().unwrap() 0x563caaf3bb50
But when I uncomment the if statement the following error is thrown:
error[E0369]: binary operation `==` cannot be applied to type `&Test`
--> src/main.rs:20:17
|
20 | if item == test.last().unwrap() {
| ---- ^^ -------------------- &Test
| |
| &Test
|
= note: an implementation of `std::cmp::PartialEq` might be missing for `&Test`
How can I compare only the two pointers?

When you compare pointers you are actually comparing the values pointed by those. This is because there are a lot of implementations in std of the type:
impl<'_, '_, A, B> PartialEq<&'_ B> for &'_ A
where
A: PartialEq<B> + ?Sized,
B: ?Sized,
that do exactly that.
If you want to compare the pointers themselves you can use std::ptr::eq:
pub fn eq<T: ?Sized>(a: *const T, b: *const T) -> bool
Note that even though it takes raw pointers, it is safe because it does not dereference the pointers. Since there is an automatic coercion from a reference to a raw pointer, you can use:
if std::ptr::eq(item, test.last().unwrap()) {
println!("Last item!");
}

Related

Rust – moved variable forbids to borrow itself ("dropped here while still borrowed")

I'm trying to write a program that generates mathematical expressions and then evaluates them. Expressions can contain primitive operations (plus, minus, etc.) or other sub-expressions that consist of primitive operations.
The problem is that sub-expressions are local for the created expression and won't be needed anywhere else except their parent expression (so, I should not make them static), but I can't move parent expression somewhere, because local sub-expressions considered as dropped even if I move them to the parent expression struct.
Minimal example:
Rust Playground
trait Operation {
fn compute(&self) -> i32;
}
struct SumNumbers {
pub numbers: Vec<i32>,
}
impl Operation for SumNumbers {
fn compute(&self) -> i32 {
let mut result = 0;
for x in &self.numbers {
result += x;
}
result
}
}
struct Expression<'a> {
pub operations: Vec<&'a dyn Operation>,
sub_expr_holder: Vec<Expression<'a>>,
}
// Not working attempt to ensure sub_expr_holder will live longer than operations
// struct Expression<'a, 'b : 'a> {
// pub operations: Vec<&'a dyn Operation>,
// sub_expr_holder: Vec<Expression<'a, 'b>>,
// }
impl Operation for Expression<'_> {
fn compute(&self) -> i32 {
let mut result = 0;
for operation in &self.operations {
result += operation.compute();
}
result
}
}
fn build_single_expression() {
let static_sum2 = SumNumbers {
numbers: vec![1, 1],
};
let static_sum4 = SumNumbers {
numbers: vec![1, 3],
};
let static_sum6 = SumNumbers {
numbers: vec![4, 2],
};
let root_expr = {
let local_expr_sum10 = Expression {
operations: vec![&static_sum4 as &dyn Operation,
&static_sum6 as &dyn Operation],
sub_expr_holder: vec![]
};
let mut root_expr = Expression {
operations: vec![],
sub_expr_holder: vec![local_expr_sum10]
};
root_expr.operations = vec![&root_expr.sub_expr_holder[0], &static_sum2];
// Ideal option would be to keep it immutable:
// let root_expr = Expression {
// operations: vec![&local_expr_sum10, &static_sum2],
// sub_expr_holder: vec![local_expr_sum10]
// };
root_expr
};
let root_expr = &root_expr as &dyn Operation;
let result = root_expr.compute();
assert_eq!(result, 12)
}
The errors I get are:
error[E0597]: `root_expr.sub_expr_holder` does not live long enough
--> src/gep_tools/test.rs:61:38
|
50 | let root_expr = {
| --------- borrow later stored here
...
61 | root_expr.operations = vec![&root_expr.sub_expr_holder[0], &static_sum2];
| ^^^^^^^^^^^^^^^^^^^^^^^^^ borrowed value does not live long enough
...
70 | };
| - `root_expr.sub_expr_holder` dropped here while still borrowed
Even though I move the local_expr_sum10 into the root_expr, the compiler says it doesn't live long enough to be borrowed from root_expr.operations. It seems the second error explains why:
error[E0505]: cannot move out of `root_expr` because it is borrowed
--> src/gep_tools/test.rs:69:9
|
61 | root_expr.operations = vec![&root_expr.sub_expr_holder[0], &static_sum2];
| ------------------------- borrow of `root_expr.sub_expr_holder` occurs here
...
69 | root_expr
| ^^^^^^^^^
| |
| move out of `root_expr` occurs here
| borrow later used here
As I understand, the compiler assumes that I can move the root_expr.sub_expr_holder out of the root_expr struct and it will be dropped while still borrowed by root_expr.operations.
Is there a way how I can force the compiler to forbid move of root_expr.sub_expr_holder out of the struct and therefore let me borrow it? Or any other approach that will let me borrow the local sub-expressions this way?
Edit:
I want to use references specifically, because there may be a lot primitive expressions which are reused among all the expressions and it would be waste of memory to copy them each time. Also, the sub-expressions can be used in the root expression several times:
root_expr.operations = vec![&root_expr.sub_expr_holder[0], &static_sum2, &root_expr.sub_expr_holder[0]];
This doesn't make a lot of sense in this minimal example, but in my full code arguments can be passed to the sub-expressions, so it makes sense to put them in a single expression several times. So, again, it would be a waste of memory to copy them multiple times.
Someone marked this question as a duplicate of "self-referential struct problem" (it was re-opened since then), but as I said, this is just 1 of my attempts to solve my problem. As it turned out, the actual problem is called "Multiple Ownership" and as Chayim Friedman suggested, it can be solved with Rc.
As a simple conclusion: if you need to use a local struct that will be dropped at the end of the scope, but you can not move it and have to use references, then go with a reference counter.
A good place to read about Rc and multiple ownership is the Rust Book.
My solution:
Rust Playground
use std::rc::Rc;
trait Operation {
fn compute(&self) -> i32;
}
struct SumNumbers {
pub numbers: Vec<i32>,
}
impl Operation for SumNumbers {
fn compute(&self) -> i32 {
let mut result = 0;
for x in &self.numbers {
result += x;
}
result
}
}
struct Expression {
pub operations: Vec<Rc<dyn Operation>>,
}
impl Operation for Expression<> {
fn compute(&self) -> i32 {
let mut result = 0;
for operation in &self.operations {
result += operation.compute();
}
result
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn build_single_expression() {
let static_sum2 = SumNumbers {
numbers: vec![1, 1],
};
let static_sum4 = SumNumbers {
numbers: vec![1, 3],
};
let static_sum6 = SumNumbers {
numbers: vec![4, 2],
};
let root_expr = {
let local_expr_sum10: Rc<dyn Operation> = Rc::new(
Expression {
operations: vec![Rc::new(static_sum4),
Rc::new(static_sum6)]
});
Expression {
operations: vec![Rc::clone(&local_expr_sum10),
Rc::clone(&local_expr_sum10),
Rc::new(static_sum2)],
}
};
let root_expr = &root_expr as &dyn Operation;
let result = root_expr.compute();
assert_eq!(result, 22)
}
}
I'm not sure how good this solution is, but it completely solves my problem, and it should not affect performance.

Dynamically create a range in either direction in Rust

I am learning Rust and recently went through an exercise where I had to iterate through numbers that could go in either direction. I tried the below with unexpected results.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
struct Point {
x: i32,
y: i32
}
fn test() {
let p1 = Point { x: 1, y: 8 };
let p2 = Point { x: 3, y: 6 };
let all_x = p1.x..=p2.x;
println!("all_x: {:?}", all_x.clone().collect::<Vec<i32>>());
let all_y = p1.y..=p2.y;
println!("all_y: {:?}", all_y.clone().collect::<Vec<i32>>());
let points: Vec<Point> = all_x.zip(all_y).map(|(x, y)| Point { x, y }).collect();
println!("points: {:?}", points);
}
The output was
all_x: [1, 2, 3]
all_y: []
points: []
After some googling I found an explanation and some old answers which basically amount to use (a..b).rev() as needed.
My question is, how do I do this in a dynamic way? If I use an if...else like so
let all_x = if p1.x < p2.x { (p1.x..=p2.x) } else { (p2.x..=p1.x).rev() };
I get a type error because the else is different than the if
|
58 | let all_x = if p1.x < p2.x { (p1.x..=p2.x) }
| - ------------- expected because of this
| _________________|
| |
59 | | else { (p2.x..=p1.x).rev() };
| |____________^^^^^^^^^^^^^^^^^^^_- `if` and `else` have incompatible types
| |
| expected struct `RangeInclusive`, found struct `Rev`
|
= note: expected type `RangeInclusive<_>`
found struct `Rev<RangeInclusive<_>>`
After trying a bunch of different variations on let all_x: dyn Range<Item = i32>, let all_x: dyn Iterator<Item = i32>, etc, the only way I have managed to do this is by turning them into collections and then back to iterators.
let all_x: Vec<i32>;
if p1.x < p2.x { all_x = (p1.x..=p2.x).collect(); }
else { all_x = (p2.x..=p1.x).rev().collect(); }
let all_x = all_x.into_iter();
println!("all_x: {:?}", all_x.clone().collect::<Vec<i32>>());
let all_y: Vec<i32>;
if p1.y < p2.y { all_y = (p1.y..=p2.y).collect(); }
else { all_y = (p2.y..=p1.y).rev().collect(); }
let all_y = all_y.into_iter();
println!("all_y: {:?}", all_y.clone().collect::<Vec<i32>>());
which provides the desired outcome
all_x: [1, 2, 3]
all_y: [8, 7, 6]
points: [Point { x: 1, y: 8 }, Point { x: 2, y: 7 }, Point { x: 3, y: 6 }]
but is a bit repetitive, inelegant and I'm assuming not very efficient at large numbers. Is there a better way to handle this situation?
NOTE: Sorry for including the Point struct. I could not get my example to work with x1, x2, etc. Probably a different question for a different post lol.
You can dynamically dispatch it. Wrapping them into a Box and returning a dynamic object, an Iterator in this case. For example:
fn maybe_reverse_range(init: usize, end: usize, reverse: bool) -> Box<dyn Iterator<Item=usize>> {
if reverse {
Box::new((init..end).rev())
} else {
Box::new((init..end))
}
}
Playground
The enum itertools::Either can be used to solve the incompatible type error in the if/else statement. A function like get_range_iter below using Either can reduce the code repetition.
use itertools::Either;
fn get_range_iter(start: i32, end: i32) -> impl Iterator<Item=i32> {
if start < end {
Either::Left(start..=end)
} else {
Either::Right((end..=start).rev())
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
struct Point {
x: i32,
y: i32
}
fn main() {
let p1 = Point { x: 1, y: 8 };
let p2 = Point { x: 3, y: 6 };
let all_x = get_range_iter(p1.x, p2.x);
let all_y = get_range_iter(p1.y, p2.y);
println!("all_x: {:?}", all_x.collect::<Vec<_>>());
println!("all_y: {:?}", all_y.collect::<Vec<_>>());
}
Playground

How to solve error "cannot borrow `*self` as mutable more than once at a time" [duplicate]

This question already has answers here:
How to borrow two disjoint fields when the borrow is behind a method call?
(1 answer)
cannot borrow `*self` as mutable more than once at a time
(1 answer)
Closed 1 year ago.
I am new to Rust. Here is a piece of code for computer stock transaction. The Strategy will buy some stocks when the SignalTrigger triggers, and sell those stocks if after 30s/90s in different way. The code can't be compiled. Here is the code:
use std::cmp;
use std::cmp::Ordering;
use std::collections::BTreeMap;
use std::collections::BinaryHeap;
use std::convert::TryFrom;
use std::error::Error;
use std::fs::File;
use std::io;
use std::process;
#[derive(Debug)]
struct Depth {
ts: u32,
ap_vec: Vec<f64>,
bp_vec: Vec<f64>,
av_vec: Vec<u32>,
bv_vec: Vec<u32>,
}
struct Order {
ts: u32,
id: u32,
is_buy: bool,
is_mkt: bool,
vol: u32,
price: f64,
}
struct LongPosition {
vol_left: u32,
ts: u32,
}
struct Strategy {
order_id: u32,
prev_buy_ts: u32,
map_orderid_position: BTreeMap<u32, LongPosition>, // map<order_id, volume_left>
}
impl Strategy {
fn on_depth(&mut self, depth: &Depth) -> Vec<Order> {
let mut orders_vec: Vec<Order> = Vec::new();
for (order_id, long_position) in &mut self.map_orderid_position {
if depth.ts - long_position.ts > 90 * 1000 {
let order = self.make_order(depth.ts, false, true, long_position.vol_left, 0.0);
orders_vec.push(order);
} else if depth.ts - long_position.ts > 60 * 1000 {
let order = self.make_order(depth.ts,false,true,long_position.vol_left,depth.bp_vec[0]);
orders_vec.push(order);
}
}
return orders_vec;
}
fn make_order(&mut self, ts: u32, is_buy: bool, is_mkt: bool, vol: u32, price: f64) -> Order {
let order = Order {
id: self.order_id,
ts,
is_buy,
is_mkt,
vol,
price,
};
self.order_id = self.order_id + 1;
return order;
}
}
fn main() {
let empty_price_vec: Vec<f64> = Vec::new();
let map_orderid_position: BTreeMap<u32, LongPosition> = BTreeMap::new();
let mut strategy = Strategy {
prev_buy_ts: 0,
order_id: 0,
map_orderid_position: map_orderid_position,
};
}
The compile says:(I have comment line 88 and line 90 in the snippet)
error[E0499]: cannot borrow `*self` as mutable more than once at a time
--> src\main.rs:46:29
|
44 | for (order_id, long_position) in &mut self.map_orderid_position {
| ------------------------------
| |
| first mutable borrow occurs here
| first borrow later used here
45 | if depth.ts - long_position.ts > 90 * 1000 {
46 | let order = self.make_order(depth.ts, false, true, long_position.vol_left, 0.0);
| ^^^^ second mutable borrow occurs here
error[E0499]: cannot borrow `*self` as mutable more than once at a time
--> src\main.rs:49:29
|
44 | for (order_id, long_position) in &mut self.map_orderid_position {
| ------------------------------
| |
| first mutable borrow occurs here
| first borrow later used here
...
49 | let order = self.make_order(depth.ts,false,true,long_position.vol_left,depth.bp_vec[0]);
| ^^^^ second mutable borrow occurs here
error: aborting due to 2 previous errors; 12 warnings emitted
For more information about this error, try `rustc --explain E0499`.
error: could not compile `greeting`
I am a little confused about Rust, snippets like these are really common in other languages. Can you make an explanation and tell me how to fix(avoid) this situation?
You are borrowing the whole instance when you are calling self.make_order. The compiler cant be sure that you are not going the change map_orderid_position. Instead, you can create a standalone function and pass the mutable reference to order_id field to it.
impl Strategy {
fn on_depth(&mut self, depth: &Depth) -> Vec<Order> {
let mut orders_vec: Vec<Order> = Vec::new();
for (order_id, long_position) in &mut self.map_orderid_position {
if depth.ts - long_position.ts > 90 * 1000 {
let order = make_order(depth.ts, false, true, long_position.vol_left, 0.0, &mut self.order_id);
orders_vec.push(order);
} else if depth.ts - long_position.ts > 60 * 1000 {
let order = make_order(depth.ts,false,true,long_position.vol_left,depth.bp_vec[0], &mut self.order_id);
orders_vec.push(order);
}
}
return orders_vec;
}
}
fn make_order(ts: u32, is_buy: bool, is_mkt: bool, vol: u32, price: f64, order_id: &mut u32) -> Order {
let order = Order {
id: *order_id,
ts,
is_buy,
is_mkt,
vol,
price,
};
*order_id += 1;
return order;
}
Instead of updating self.order_id in the function make_order() you can update it in the function on_depth(). Then you don't have to use &mut self for make_order() and the problem is solved.
Example:
impl Strategy {
fn on_depth(&mut self, depth: &Depth) -> Vec<Order> {
let mut orders_vec: Vec<Order> = Vec::new();
for (order_id, long_position) in &self.map_orderid_position {
let order = if depth.ts - long_position.ts > 90 * 1000 {
self.make_order(depth.ts, false, true, long_position.vol_left, 0.0)
} else if depth.ts - long_position.ts > 60 * 1000 {
self.make_order(depth.ts, false, true, long_position.vol_left, depth.bp_vec[0])
} else {
continue;
};
orders_vec.push(order);
self.order_id += 1; // Update `self.order_id` here
}
return orders_vec;
}
// Changed `&mut self` to `&self`
fn make_order(&self, ts: u32, is_buy: bool, is_mkt: bool, vol: u32, price: f64) -> Order {
let order = Order {
id: self.order_id,
ts,
is_buy,
is_mkt,
vol,
price,
};
// Removed `self.order_id = self.order_id + 1`
return order;
}
}
From the book:
The benefit of having this restriction is that Rust can prevent data
races at compile time. A data race is similar to a race condition and
happens when these three behaviors occur:
Two or more pointers access the same data at the same time.
At least one of the pointers is being used to write to the data.
There’s no mechanism being used to synchronize access to the data.
Data races cause undefined behavior and can be difficult to diagnose
and fix when you’re trying to track them down at runtime; Rust
prevents this problem from happening because it won’t even compile
code with data races!
I don't know what the best practice is but I would generally make a clone of the variable for reading, for, example:
fn main() {
let mut s = String::from("hello");
let r1 = s.clone(); // if this was &mut s, I'll get the same error
let r2 = &mut s;
println!("{}, {}", r1, r2);
}
So, you could probably try making clone of self.map_orderid_position since you are just reading values from it.

How to iterate through FnvHashMap in Rust

I have two FnvHashMap which is declared like first: FnvHashMap<(i32, i32), Employee>
second: FnvHashMap<(i32, i32), Employee>
Where Employee is
pub struct Employee {
pub emp_id: i32,
pub lang_id: i32,
pub dept_id: f64,
pub description: String,
}
I need to iterate through 'first' FnvHashMap and see if there is a matching record(emp_id and lang_id) in 'second' FnvHashMap
I may not need to consider dept_id and description
Thanks in Advance.
New code after implementing nested loop
for (_, employee1) in &first {
for (_, employee2) in &second {
if employee1.emp_id == employee2.emp_id && employee1.lang_id == employee2.lang_id {
values.push(OldNew {
old: employee2,
new: employee1,
});
}
}
}
let new = first
.into_iter()
.filter(|(a, _)| !old.contains_key(a))
.map(|(_, a)| a)
.collect();
let deleted = second
.iter()
.filter(|(a, _)| !new.contains_key(a))
.map(|(&a, _)| a)
.collect();
Changes {
deleted,
new,
values,
}
pub struct Changes<T, I> {
pub deleted: Vec<I>,
pub new: Vec<T>,
pub values: Vec<OldNew<T>>,
}
expected struct `organization::models::employee_stat::Employee`, found `&organization::models::employee_stat::Employee`
Simply make two nested for loops to iterate through both maps and then compare the values you need from the two iterations of the loops, for example
for (_, employee1) in &first {
for (_, employee2) in &second {
if employee1.emp_id == employee2.emp_id && employee1.lang_id == employee2.lang_id {
/* Code here to run if a matching value is found */
}
}
}

Unable to mutably borrow the contents inside a RefCell, even after the scope of the previous mutable borrow has ended

Consider the following bit of code
use std::{cell::RefCell, rc::Rc};
type NodeRef = Rc<RefCell<_Node>>;
#[derive(Debug)]
struct _Node {
id: usize,
data: Option<NodeRef>,
edges: Vec<NodeRef>,
}
impl _Node {
fn add(&mut self, other: NodeRef) {
println!("at {}", self.id);
self.data = match self.data.take() {
Some(current_data) => {
{
let mut current_data_raw = current_data.borrow_mut();
current_data_raw.id += other.borrow().id;
}
Some(current_data)
}
None => Some(Rc::clone(&other)),
};
for e in &self.edges {
e.borrow_mut().add(Rc::clone(&other));
}
println!("done {}", self.id);
}
}
#[derive(Debug)]
struct Node(NodeRef);
impl Node {
fn new(id: usize) -> Node {
Node(Rc::new(RefCell::new(_Node {
id,
data: None,
edges: vec![],
})))
}
fn add_edge(&self, other: &Node) {
self.0.borrow_mut().edges.push(Rc::clone(&other.0));
}
fn add(&self, other: Self) {
self.0.borrow_mut().add(other.0);
}
}
fn main() {
let a = Node::new(0);
let b = Node::new(1);
let c = Node::new(2);
let d = Node::new(3);
let e = Node::new(4);
let f = Node::new(5);
d.add_edge(&a);
d.add_edge(&b);
e.add_edge(&b);
e.add_edge(&c);
f.add_edge(&d);
f.add_edge(&e);
f.add(Node::new(6));
}
The output generated on running this is
at 5
at 3
at 0
done 0
at 1
done 1
done 3
at 4
at 1
thread 'main' panicked at 'already mutably borrowed: BorrowError', src/libcore/result.rs:1009:5
This creates a graph of the form
F--E--A
\ \
\ B
\ /
D
\
C
I am trying to propagate a value through the entire graph, so it starts from F, and goes to E and D. From E it goes to A and B without any error. Then from D, the runtime panics saying the RefCell constraint for mutable borrows has been broken.
It seems that it is considering the mutable borrow from the previous invocation of the callback with B, however, the mutable borrow (current_data_raw) inside _Node::add has a limited scope, and after the scope ends, I should be allowed to mutably borrow the value again. From the output, when the function is called for node B for the second time, the entire first invocation of the function and not just the mutable borrow scope has exited.
What am I missing here?
What am I missing here?
Your algorithm is broken. You can see this by adding this debugging code inside of the Some arm of the match:
{
let a = current_data.borrow();
let b = other.borrow();
assert_ne!(a.id, b.id);
}
This fails:
thread 'main' panicked at 'assertion failed: `(left != right)`
left: `6`,
right: `6`', src/main.rs:23:25
You are trying to borrow the exact same node twice at the same time.

Resources