What is the idiomatic way to print a Vec as a string? - string

Updating my code to the new nightlies and it seems like they've gotten rid of to_string() for std::Vec
src/rust_mnemonic.rs:100:39: 100:50 error: type `collections::vec::Vec<&str>` does not implement any method in scope named `to_string`
rc/rust_mnemonic.rs:100 println!("mnemonic: {}", mnemonic.to_string());

You can use the :? specifier, which uses the Debug trait.
fn main() {
let v = vec![0u8, 1, 2, 3, 4, 5];
println!("{:?}", v);
}
If you want it as a String, then you can use format!:
fn main() {
let v = vec![0u8, 1, 2, 3, 4, 5];
let s = format!("{:?}", v);
println!("-->{}<--", s);
}

Related

How to return a PyTuple in rust using pyo3?

I want a function that simply creates and returns a tuple as an example.
Basic template starting code (maturin new) looks like:
use pyo3::prelude::*;
/// Formats the sum of two numbers as string.
#[pyfunction]
fn sum_as_string(a: usize, b: usize) -> PyResult<String> {
Ok((a + b).to_string())
}
/// A Python module implemented in Rust.
#[pymodule]
fn tuple(_py: Python, m: &PyModule) -> PyResult<()> {
m.add_function(wrap_pyfunction!(sum_as_string, m)?)?;
Ok(())
}
I have tried something like this but can't figure out what combination of things is required to even compile.
#[pyfunction]
fn f_ret_tuple() -> PyResult<&'static PyTuple> {
let gil = Python::acquire_gil();
let py = gil.python();
let tuple: &PyTuple;
let elements: Vec<i32> = vec![0, 1, 2, 3, 4, 5];
tuple = PyTuple::new(py, elements);
Ok(tuple)
}
The problem is that the compiler can't prove your tuple will not outlive the GIL acquisition. But per the docs,
In a function or method annotated with #[pyfunction] or #[pymethods] you can declare it as a parameter, and PyO3 will pass in the token when Python code calls it.
So:
#[pyfunction]
fn f_ret_tuple(py: Python<'_>) -> PyResult<&PyTuple> {
let tuple: &PyTuple;
let elements: Vec<i32> = vec![0, 1, 2, 3, 4, 5];
tuple = PyTuple::new(py, elements);
Ok(tuple)
}

how to convert Option<&u8> to u8

i want to convert Option<&u8> to u8 so i will be able to print it
my code:
fn main() {
let v : Vec<u8> = vec![1, 2, 3, 4, 5];
let out_of_range = &v[100];
let out_of_range = v.get(100);
match out_of_range{
Some(&u8) => println!("data out of range: {}", out_of_range),
None => println!("bruh"),
}
}
Your match statement needs the introduction of a binding, not a type (the &u8 you used was not expected here).
Here Some(val) matches with something which is an Option<&u8>, thus val is a binding to the embedded &u8 (if not None, of course).
The example explicitly dereferences val as an illustration, and highlights the fact that val is not an u8 but a reference, but it's not required for the following operation (printing).
fn main() {
let v: Vec<u8> = vec![1, 2, 3, 4, 5];
for idx in [2, 20, 4] {
let at_index = v.get(idx);
match at_index {
Some(val) => {
// val has type &u8
let copy_of_val = *val; // not required, just for the example
println!("at {} --> {}", idx, copy_of_val);
}
None => println!("no value at {}", idx),
}
}
}

Insert into Rust array in place, push other elements down

I'm trying to do the following in Rust, specifically using arrays (I don't want to use vectors here, and want elements pushed out of the array if we're done).
let mut x = [1, 2, 3, 4, 5];
// array, number to insert, place to be inserted at
insert_in_place(&x, 7, 1);
// x is now [1, 7, 2, 3, 4];
How do you implement insert_in_place?
I think there's a way to do this using slices, but I'm still learning and wondering if there's a really elegant way to do this kind of thing.
fn insert_in_place<T>(array: &mut [T], value: T, index: usize) {
*array.last_mut().unwrap() = value;
array[index..].rotate_right(1);
}
Try it online!
Or equivalently:
fn insert_in_place<T>(array: &mut [T], value: T, index: usize) {
array[index..].rotate_right(1);
array[index] = value;
}
Try it online!
Iterate the slice, skipping elements before the index of the one you need to insert. Then swap each element with its previous element (or, for the first one, use the item to add).
fn insert_in_place<T>(x: &mut [T], new: T, index: usize) {
let mut next = new;
for e in x.iter_mut().skip(index) {
std::mem::swap(e, &mut next);
}
}
fn main() {
let mut x = [1, 2, 3, 4, 5];
// array, number to insert, place to be inserted at
insert_in_place(&mut x, 7, 1);
// x is now [1, 7, 2, 3, 4];
println!("{:?}", x);
}

How to obtain the chunk index in Rayon's par_chunks_mut

I have some data and I want to process it and use it to fill an array that already exists. For example suppose I want to repeat each value 4 times (playground):
use rayon::prelude::*; // 1.3.0
fn main() {
let input = vec![4, 7, 2, 3, 5, 8];
// This already exists.
let mut output = vec![0; input.len() * 4];
output.par_chunks_mut(4).for_each(|slice| {
for x in slice.iter_mut() {
*x = input[?];
}
});
}
This almost works but Rayon doesn't pass the chunk index to me so I can't put anything in input[?]. Is there an efficient solution?
The easiest thing to do is avoid the need for an index at all. For this example, we can just zip the iterators:
use rayon::prelude::*; // 1.3.0
fn main() {
let input = vec![4, 7, 2, 3, 5, 8];
let mut output = vec![0; input.len() * 4];
// Can also use `.zip(&input)` if you don't want to give up ownership
output.par_chunks_mut(4).zip(input).for_each(|(o, i)| {
for o in o {
*o = i
}
});
println!("{:?}", output)
}
For traditional iterators, this style of implementation is beneficial as it avoids unneeded bounds checks which would otherwise be handled by the iterator. I'm not sure that Rayon benefits from the exact same thing, but I also don't see any reason it wouldn't.
Rayon provides an enumerate() function for most of its iterators that works just like the non-parallel counterpart:
let input = vec![4, 7, 2, 3, 5, 8];
let mut output = vec![0; input.len() * 4];
output.par_chunks_mut(4).enumerate().for_each(|(i, slice)| {
for x in slice.iter_mut() {
*x = input[i];
}
});

How to get Deref coercion when using impl Trait

This function returns the first element of a list-like collection. It works for a variety of different list-like types:
fn first<T: Copy>(x: impl Deref<Target=[T]>) -> T {
x[0]
}
For example, this compiles and runs:
let data: Vec<usize> = vec![3, 4];
assert_eq!(first(data), 3);
let data: &[usize] = &[3, 4];
assert_eq!(first(data), 3);
let data: Rc<[usize]> = Rc::new([3, 4]);
assert_eq!(first(data), 3);
This also compiles and runs:
fn stub(x: &[usize]) -> usize {
first(x)
}
let data: &[usize; 2] = &[3, 4];
assert_eq!(stub(data), 3);
assert_eq!(stub(&[3, 4]), 3);
But this fails to compile:
let data: &[usize; 2] = &[3, 4];
assert_eq!(first(data), 3); // Fails.
assert_eq!(first(&[3, 4]), 3); // Fails.
The error message is:
type mismatch resolving `<&[usize; 2] as std::ops::Deref>::Target == [_]`
I think I understand what is going on. For each type T there is a unique type <T as Deref>::Target. When T is &[usize; 2] the target is [usize; 2], not [usize]. The compiler is able to coerce &[T; 2] to &[T] if I explicitly ask it to, e.g. by using let or stub(), but if I don't then it's not able to work out that the coercion is required.
But it's frustrating. It's perfectly obvious to a human what the failing calls are intended to do, and the compiler understands what's required for Vec<usize>, Box<[usize]>, Rc<[usize]>, &[usize] and so on, so it doesn't seem unreasonable to try to make it work for [usize; 2] as well.
Question: Is there a convenient way to write first() so that the last two calls work too? If not, is there a syntax to ask the compiler to coerce a &[usize; 2] to a &[usize] inline, i.e. without using let or stub()?
Playground.
You want to use AsRef, not Deref:
use std::rc::Rc;
fn first<T: Copy>(x: impl AsRef<[T]>) -> T {
x.as_ref()[0]
}
fn main() {
let data: Vec<usize> = vec![3, 4];
assert_eq!(first(data), 3);
let data: &[usize] = &[3, 4];
assert_eq!(first(data), 3);
let data: Rc<[usize]> = Rc::new([3, 4]);
assert_eq!(first(data), 3);
let data: &[usize; 2] = &[3, 4];
assert_eq!(first(data), 3);
}

Resources