Closure with Box<T> arguments in Rust - rust

I want to know how to code Closure(function) with Box argument in Rust.
For just , it's simple.
fn main() {
let a = 5;
let double = |x| 2 * x;
let b = double(a); //10
}
now, for Box
fn main() {
let a = Box::new(5);
let double = |x| 2 * x; //how to write?
let b = double(a);
}
I don't know what is the adequate or smart way to code, and for unknown reason, the official document or Google did not help.
Please advise.

Here is an example how you can do that:
fn main() {
let a = Box::new(5);
let double = |x: Box<i32>| 2 * *x;
let b = double(a);
print!("{b}")
}
First, you need to specify the closure parameter type in this case. Instead of Box<i32>, you can also write Box<_>.
Next, you need to get the value owned by the Box via *x.

Related

How to use feature flag in Rust to capture multiple lines of code?

I realized that doing something like the following does not work in Rust as it throws temp not found error, because it seems the braces around #[cfg(not(feature = "my-feature"))] create a new scope, right?:
fn main() {
#[cfg(not(feature = "my-feature"))] {
let temp: usize = 1;
}
let mut output = 0;
#[cfg(not(feature = "my-feature"))]
output = temp + 1;
println!("output: {:?}", output);
}
But what's the proper way then to enclose multiple lines with a feature flag in Rust without introducing a new scope (i.e., to re-use the existing variables later)?
You can use/abuse the fact that blocks are expressions to write something like this.
#[cfg(stuff)]
let (x, y, z) = {
let x = ...;
let y = ...;
let z = ...;
(x, y, z)
}
let mut output = 0;
#[cfg(stuff)]
println!("{x}, {y}, {z}");
Its not pretty, but it's better than adding the #[cfg(stuff)] to every line

Different types of string.chars(), for .next() and .peek()

I'm trying to use string.chars().peekable() and the problem I have is that I have different types from .next() and .peek(). One is Option<char>, second is Option<&char>, and I have trouble to compare them.
My code is (s is String):
let mut left_iter = s.chars().peekable();
let mut right_iter = s.chars().rev().peekable();
loop {
let left = left_iter.next();
let right = right_iter.next();
let left_next = left_iter.peek();
let left_right = right_iter.peek();
if left == right || left == right_next {
...
}
The error I get is obvious:
expected &char, found char
But I can't find a way to have both next() and peek() having the same type without re/deconstructing Option.
Is there a clean way to have both return values having the same type?
You have two options derefenccing (&T -> T) one or referencing (T -> &T) the other:
Dereferencing
Since they are wrapped in Option, you could zip them and operate over with map, pattern match or dereference the referenced one, otherwise return false.:
fn main() {
let left = Some('c');
let right = Some(&'c');
println!("{}", right.zip(left).map(|(&r, l)| r == l).unwrap_or(false));
}
Playground
Or since char is Copy, you could use Option::copied:
fn main() {
let left = Some('c');
let right = Some(&'c');
println!("{}", left == right.copied());
}
Referencing
Also, and maybe simpler, you could use as_ref to get an Option<&T> from an Option<T>:
fn main() {
let left = Some('c');
let right = Some(&'c');
println!("{}", left.as_ref() == right);
}
Playground

How to define a function in Rust?

I decided to do 2D vector cross product in Rust. In JavaScript, this is simple to do:
float CrossProduct( const Vec2& a, const Vec2& b ) {
return a.x * b.y - a.y * b.x;
}
I tried to convert it to the Rust system:
// Just created two separate variables for the two different vectors
let vec1 = vec![1.15, 7.0];
let vec2 = vec![7.0, 2.0];
let cross_product(&vec1, &vec2) = vec1[0] * vec2[1] - vec1[1] * vec2[0];
println!("{}", cross_product);
// I also tried return.
let vec1 = vec![1.15, 7.0];
let vec2 = vec![7.0, 2.0];
let cross_product(&vec1, &vec2) {
return (vec1[0] * vec2[1] - vec1[1] * vec2[0]);
}
println!("{}", cross_product);
I thought that one of these would work, however this was more of a reality check to me how different Rust can be from any language I have used previously.
I found a very inefficient way to work around this, however I would rather learn to do this correctly. I am new to Rust, so please take my attempts with a grain of salt.
There are two possible ways to do this.
First Way
You can declare a function and pass it into println!() which is similar to many programming languages like Java, C#, etc.
// Declare the function
fn cross_product(slice1: &[i32], slice2: &[i32]) -> i32 {
slice1[0] * slice2[1] - slice1[1] * slice2[2]
}
// Use it Like following
fn main() {
let vec1 = vec![1, 2, 3];
let vec2 = vec![4, 5, 6];
println!("{}", cross_product(&vec1[..], &vec2[..]));
}
Second Way
You can declare a closure and pass it into println!(), a common methodology in functional programming:
// You can declare a closure and use it as function in the same code block
fn main() {
let vec1 = vec![1, 2, 3];
let vec2 = vec![4, 5, 6];
let cross_product = |slice1: &[i32], slice2: &[i32]| -> i32 {
let result = slice1[0] * slice2[1] - slice1[1] * slice2[2];
result
};
println!("{}", cross_product(&vec1[..], &vec2[..]));
}
Please note that I have created the vectors and closures using the i32 data type, which corresponds to an integer. You can change the type with f32 or if you want wider float range f64.
It looks like you are mainly having problems with Rust syntax. You can either create a cross product function or do the cross product inline.
let vec1 = vec![1.15, 7.0];
let vec2 = vec![7.0, 2.0];
let cross_product = vec1[0] * vec2[1] - vec1[1] * vec2[0];
println!("{}", cross_product);
If you want a function you can use continually.
fn function_cross_product(vec1: Vec<f64>, vec2: Vec<f64>) -> f64 {
return vec1[0] * vec2[1] - vec1[1] * vec2[0];
};
let other_product = function_cross_product(vec1, vec2);
println!("{}", other_product);
The second solution can be misleading because it will always produce the cross product for a 2x2 vector even if you pass different sized vectors.

Is it necessary to cast to float to access basic math functions in Rust?

fn main() {
let a = 1i32;
let b = 2i32;
let smallest = (a as f64).min((b as f64)) as i32;
println!("{}", smallest);
}
Is all the casting to and from floats really necessary?
The function you're looking for is ::std::cmp::min, which works on any type that implements Ord:
fn main() {
let a = 1i32;
let b = 2i32;
let smallest = ::std::cmp::min(a, b);
println!("{}", smallest);
}
You were using the min method from f64 (an equivalent exists for f32).
No. As a quick search of the API reference reveals, you can just use std::cmp::min:
use std::cmp::min;
fn main() {
let a = 1i32;
let b = 2i32;
let smallest = min(a, b);
println!("{}", smallest);
}
min being declared specially on f32 and f64 is because floating point types do not implement Ord. Due to the presence of NaN, they only have partial ordering (PartialOrd) whilst std::cmp::min requires a total ordering (Ord).

Creating a macro with infinte arguments

struct Foo{
value: i32
}
impl Foo{
fn get_and_change_value(&mut self) -> i32{
let v = self.value;
self.value = 42;
v
}
}
//glue_code_macro
fn main(){
let mut f1 = Foo{value:1};
let mut f2 = Foo{value:2};
let mut f3 = Foo{value:3};
let v: Vec<i32> = glue_code_macro!(f1,f2,f3);
}
I want to create the glue_code_macro which takes n variables and creates a vector. I don't think that I can achieve this with a normal function because I have a mutable reference and I would be unable to change its content.
In my head it would expand to
let v = {
let v1 = f1.get_and_change_value();
let v2 = f2.get_and_change_value();
let v3 = f3.get_and_change_value();
vec!(v1,v2,v3)
}
Is this possible? If yes how would I do this?
It's possible. Add this to the top of your module:
#![feature(macro_rules)]
macro_rules! glue_code_macro(
($($element:ident),*) => (
vec![$($element.get_and_change_value(),)*]
)
)
The macro guide explains how it works: http://doc.rust-lang.org/guide-macros.html

Resources