How do I convert an &i32 to f64? - rust

I'm trying to solve an exercise at the end of this chapter in the Rust Book.
Here is a code sample:
fn mean(v: &Vec<i32>) -> f64 {
let mut sum = 0.0;
let mut count = 0.0;
for val in v {
sum += &f64::from(val);
count += 1.0;
}
sum / count
}
fn main() {
let v = vec![1, 2, 3, 4];
println!("The mean is {}", mean(&v));
}
The error is:
error[E0277]: the trait bound `f64: std::convert::From<&i32>` is not satisfied
--> src/main.rs:6:17
|
6 | sum += &f64::from(val);
| ^^^^^^^^^ the trait `std::convert::From<&i32>` is not implemented for `f64`
|
= help: the following implementations were found:
<f64 as std::convert::From<f32>>
<f64 as std::convert::From<i16>>
<f64 as std::convert::From<i32>>
<f64 as std::convert::From<i8>>
and 3 others
= note: required by `std::convert::From::from`
I also tried using the as keyword but it didn't help.

f64 only implements From for i32, not &i32 (which is a reference to an i32). To get this to work, you will need to dereference val.
fn mean(v: &Vec<i32>) -> f64 {
let mut sum = 0.0;
let mut count = 0.0;
for val in v {
sum += f64::from(*val);
count += 1.0;
}
sum / count
}
The same applies if you try to do val as f64, and in fact, you get a much more helpful error message in that case:
error[E0606]: casting `&i32` as `f64` is invalid
--> src/main.rs:6:16
|
6 | sum += val as f64;
| ---^^^^^^^
| |
| cannot cast `&i32` as `f64`
| help: dereference the expression: `*val`

You can dereference the variable with *val as f64.
fn mean(v: &Vec<i32>) -> f64 {
let mut sum = 0.0;
let mut count = 0.0;
for val in v {
sum += *val as f64;
count += 1.0;
}
sum / count
}
fn main() {
let v = vec![1, 2, 3, 4];
println!("The mean is {}", mean(&v));
}
Another way to do it
fn main() {
let v = vec![1, 2, 3, 4];
let mean: f64 = v.iter().map(|&val| val as f64).sum::<f64>() / v.len() as f64;
println!("The mean is {}", mean);
}

Related

Solving shuffle the array problem on leetcode in Rust

fn shuffle(nums: Vec<i32>, n: i32) -> Vec<i32> {
let mut res: Vec<i32>;
let mut i = 0;
while i < n {
res.push(nums[i]);
res.push(nums[n + i]);
i += 1;
}
res
}
When I try to index the nums array to get a value at [i], I get this error:
the type [i32] cannot be indexed by i32
the trait SliceIndex<[i32]> is not implemented for i32
required because of the requirements on the impl of Index<i32> for Vec<i32>
Any ideas how to solve this?
You can only index Vec using usizes, so you have to cast your i32s to usizes in order to index into nums:
fn shuffle(nums: Vec<i32>, n: i32) -> Vec<i32> {
let mut res = Vec::new();
let mut i = 0;
while i < n {
res.push(nums[i as usize]);
res.push(nums[(n + i) as usize]);
i += 1;
}
res
}
playground

Reason of the error expected (), found struct `std::vec::Vec` in Rust?

I am new to rust programming. I wanted to implement merge sort with recursion. Here is my code:
fn merge(a: &mut Vec<u32>, b: &mut Vec<u32>) -> Vec<u32> {
let mut temp: Vec<u32> = Vec::new();
println!("The digit is {}", a[0]);
while a.len() > 0 && b.len() > 0 {
if a[0] > b[0] {
temp.push(a[0]);
a.pop();
} else {
temp.push(b[0]);
b.pop();
}
}
while a.len() > 0 {
temp.push(a[0]);
a.pop();
}
while b.len() > 0 {
temp.push(b[0]);
b.pop();
}
temp
}
fn merge_sort(v: &mut Vec<u32>) -> Vec<u32> {
println!("The divided vector is: {:?}", v);
let n = v.len();
if n == 1 {
println!("The divided vector is: {:?}", v.to_vec());
let t: Vec<u32> = Vec::new();
t.push(v[0]);
t
}
if n == 0 {
panic!("Alas!! NULL");
}
merge(
&mut merge_sort(&mut v[0..n / 2].to_vec()),
&mut merge_sort(&mut v[n / 2 + 1..n].to_vec()),
)
.to_vec()
}
fn main() {
let mut v = vec![23, 78, 89, 64, 23, 12, 79, 45, 64];
println!("The vector is: {:?}", v);
println!("The length {}", v.len());
let v = merge_sort(&mut v);
println!("The sorted vector is: {:?}", v);
}
The problem is, when I am trying to compile it, I am getting the following error:
error[E0308]: mismatched types
--> src/main.rs:36:9
|
32 | / if n == 1 {
33 | | println!("The divided vector is: {:?}", v.to_vec());
34 | | let t: Vec<u32> = Vec::new();
35 | | t.push(v[0]);
36 | | t
| | ^ expected `()`, found struct `std::vec::Vec`
37 | | }
| | -- help: consider using a semicolon here
| |_____|
| expected this to be `()`
|
= note: expected unit type `()`
found struct `std::vec::Vec<u32>`
Do you have any idea why am I getting this strange error! It seems, I am missing something.
In Rust, the block type is the type of the final expression or () if there is none. Also combined blocks needs to be same type like if{...} else if{...} else{...}. Without an else the return type of an if expression must be () as this is the type that is returned when the expression evaluates to false.
Additionally the result is not the final expression in your code. What you need instead is to use return. Also be aware Vec::push requires a mutable reference of instance(&mut self).
if n == 1 {
println!("The divided vector is: {:?}", v.to_vec());
let mut t: Vec<u32> = Vec::new();
t.push(v[0]);
return t;
}

Is it possible to create a mutable value of a mutable reference in a pattern?

When pattern-matching, you can specify that you'd like to get a mutable reference to the contained value by using ref mut:
let mut score = Some(42);
if let Some(ref mut s) = score {
&mut s;
}
However, the inner value is not mutable:
error[E0596]: cannot borrow immutable local variable `s` as mutable
--> src/main.rs:4:14
|
4 | &mut s;
| ^
| |
| cannot reborrow mutably
| try removing `&mut` here
I tried to add in another mut, but that was not valid:
if let Some(mut ref mut s) = score {
&mut s;
}
error: the order of `mut` and `ref` is incorrect
--> src/main.rs:3:17
|
3 | if let Some(mut ref mut s) = score {
| ^^^^^^^ help: try switching the order: `ref mut`
error: expected identifier, found keyword `mut`
--> src/main.rs:3:25
|
3 | if let Some(mut ref mut s) = score {
| ^^^ expected identifier, found keyword
error: expected one of `)`, `,`, or `#`, found `s`
--> src/main.rs:3:29
|
3 | if let Some(mut ref mut s) = score {
| ^ expected one of `)`, `,`, or `#` here
Not a direct answer, but possible workarounds
Create an intermediate variable
if let Some(ref mut s) = score {
let mut s = s;
&mut s;
}
#[derive(Debug)]
struct X;
enum Foo<T> {
Bar(T),
_Baz,
}
fn main() {
let mut score = Foo::Bar(X);
if let Foo::Bar(ref mut s) = score {
//let x = s;
//println!("{:?}", **x); ! not possible
let x = &mut &mut *s; // &mut &mut X
println!("{:?}", **x);
}
}
For Option specifically
if let Some(ref mut s) = score.as_mut() {
s; //:&mut &mut i32
}
if let Some(mut s) = score.as_mut() {
&mut s;
}
Below code may give an idea for the possible solution to the problem. It's just a sample & testable code to provide a tiny example that aimed at the issue. Of course it may not cover the whole intents and purposes.
fn main() {
let mut score = Some(42i32);
let res = if let Some(41) = score {
println!("41 is matched");
1i32
} else if let Some(ref mut s) = score { //&mut score {
//let mut s2 = s;
//println!("s: {:#?}", s);
test(&mut &mut *s); // This part may be like this for borrowing
//println!("s: {:#?}", s);
1i32
} else {
0i32
};
//println!("Result: {:#?}", score);
assert_eq!(res, 1i32);
}
fn test(ref mut s: &mut &mut i32) -> i32 {
//let mut s2 = s;
return test2(&mut *s);
}
fn test2(n: &mut i32) -> i32 {
*n += 1;
//println!("Value: {}", *(*n));
return *n;
}
Live Version: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=7c3e7e1ee712a31f74b201149365035f
Gist Link: https://gist.github.com/7c3e7e1ee712a31f74b201149365035f

How do I split an integer into individual digits?

I'm writing a function that requires the individual digits of a larger integer to perform operations on.
I've tried the following:
fn example(num: i32) {
// I can safely unwrap because I know the chars of the string are going to be valid
let digits = num.to_string().chars().map(|d| d.to_digit(10).unwrap());
for digit in digits {
println!("{}", digit)
}
}
But the borrow checker says the string doesn't live long enough:
error[E0716]: temporary value dropped while borrowed
--> src/lib.rs:3:18
|
3 | let digits = num.to_string().chars().map(|d| d.to_digit(10).unwrap());
| ^^^^^^^^^^^^^^^ - temporary value is freed at the end of this statement
| |
| creates a temporary which is freed while still in use
4 | for digit in digits {
| ------ borrow later used here
|
= note: consider using a `let` binding to create a longer lived value
The following does work:
let temp = num.to_string();
let digits = temp.chars().map(|d| d.to_digit(10).unwrap());
But that looks even more contrived.
Is there a better, and possibly more natural way of doing this?
But the borrow checker says the string doesn't live long enough.
That's because it doesn't. You aren't using the iterator, so the type of digits is
std::iter::Map<std::str::Chars<'_>, <closure>>
That is, a yet-to-be-evaluated iterator that contains references to the allocated string (the unnamed lifetime '_ in Chars). However, since that string has no owner, it is dropped at the end of the statement; before the iterator is consumed.
So, yay for Rust, it prevented a use-after-free bug!
Consuming the iterator would "solve" the problem, as the references to the allocated string would not attempt to live longer than the allocated string; they all end at the end of the statement:
let digits: Vec<_> = num.to_string().chars().map(|d| d.to_digit(10).unwrap()).collect();
If you wanted to return an iterator, you can then convert the Vec back into an iterator:
fn digits(num: usize) -> impl Iterator<Item = u32> {
num.to_string()
.chars()
.map(|d| d.to_digit(10).unwrap())
.collect::<Vec<_>>()
.into_iter()
}
As for an alternate solution, there's the math way, stolen from the C++ question to create a vector:
fn x(n: usize) -> Vec<usize> {
fn x_inner(n: usize, xs: &mut Vec<usize>) {
if n >= 10 {
x_inner(n / 10, xs);
}
xs.push(n % 10);
}
let mut xs = Vec::new();
x_inner(n, &mut xs);
xs
}
fn main() {
let num = 42;
let digits: Vec<_> = num.to_string().chars().map(|d| d.to_digit(10).unwrap()).collect();
println!("{:?}", digits);
let digits = x(42);
println!("{:?}", digits);
}
However, you might want to add all the special case logic for negative numbers, and testing wouldn't be a bad idea.
You might also want a fancy-pants iterator version:
fn digits(mut num: usize) -> impl Iterator<Item = usize> {
let mut divisor = 1;
while num >= divisor * 10 {
divisor *= 10;
}
std::iter::from_fn(move || {
if divisor == 0 {
None
} else {
let v = num / divisor;
num %= divisor;
divisor /= 10;
Some(v)
}
})
}
Or the completely custom type:
struct Digits {
n: usize,
divisor: usize,
}
impl Digits {
fn new(n: usize) -> Self {
let mut divisor = 1;
while n >= divisor * 10 {
divisor *= 10;
}
Digits {
n: n,
divisor: divisor,
}
}
}
impl Iterator for Digits {
type Item = usize;
fn next(&mut self) -> Option<Self::Item> {
if self.divisor == 0 {
None
} else {
let v = Some(self.n / self.divisor);
self.n %= self.divisor;
self.divisor /= 10;
v
}
}
}
fn main() {
let digits: Vec<_> = Digits::new(42).collect();
println!("{:?}", digits);
}
See also:
What is the correct way to return an Iterator (or any other trait)?

When can I omit dereferencing with the asterisk operator?

I have a hard time understanding when to use the asterisk operator for dereferencing and when can I omit it.
fn main() { a(); b(); c(); d(); }
fn a() {
let v = 1;
let x = &v;
println!("a {}", *x);
println!("a {}", 1 + *x);
}
fn b() {
let v = 1;
let x = &v;
println!("b {}", x);
println!("b {}", 1 + x);
}
fn c() {
let mut v = 1;
let mut x = &mut v;
println!("c {}", *x);
println!("c {}", 1 + *x);
}
fn d() {
let mut v = 1;
let mut x = &mut v;
println!("d {}", x);
println!("d {}", 1 + x); // error
}
The above code sample almost compiles except the last statement where I add one to the the mutable reference x. There I get this error:
the trait bound `_: std::ops::Add<&mut _>` is not satisfied [E0277]
Anywhere else both asterisk and non-asterisk versions are valid and give expected results.
You can only add types for which the operator is defined by implementing the Add trait. In both examples where you do 1 + *x, the type of *x is i32 and indeed i32 + i32 is defined. For convenience there is also an implementation of i32 + &i32 (and &i32 + i32 and &i32 + &i32) which makes b work, but this is just for the specific case of one immutable reference, it doesn't extend to, say &&i32 or &mut i32. That's why d does not work.

Resources