Type-casting arrays/vectors in Rust
Asked Answered
L

2

20

What would be the idiomatic way of converting arrays or vectors of one type to another in Rust? The desired effect is

let x = ~[0 as int, 1 as int, 2 as int];
let y = vec::map(x, |&e| { e as uint });

but I'm not sure if the same could be achieved in a more concise fashion, similar to scalar type-casts.

I seem to fail at finding clues in the Rust manual or reference. TIA.

Lopez answered 26/5, 2013 at 0:36 Comment(0)
C
19

In general, the best you are going to get is similar to what you have (this allocates a new vector):

let x = vec![0, 1, 2];
let y = x.iter().map(|&e| e as u32).collect();

Although, if you know the bit patterns of the things you are casting between are the same (e.g. a newtype struct to the type it wraps, or casting between uint and int), you can do an in-place cast, that will not allocate a new vector (although it means that the old x can not be accessed):

let x = [0, 1, 2];
let y: [u32; 3] = unsafe { cast::transmute(x) };

(Note that this is unsafe, and can cause Bad Things to happen.)

Counterespionage answered 26/5, 2013 at 4:49 Comment(5)
Thank you. Going the usual functional way and using map will be good enough.Lopez
Looks like this answer needs an update to account for newer versions of Rust (e.g. there's no more do keyword, and I think you need .iter() and .collect() in there somewhere)Urey
Not to mention that we now have proper Box instead of whatever that squiggly meant before.Orthorhombic
@Counterespionage can this be used to cast ro a vector of a larger int type?Insignificant
Your example transmutes an array, which is fine, but your words imply you can transmute a vector. Which is definitely disallowed. The only valid way to do that is from_raw_parts(). But, better you use something like bytemuck's cast_vec(). Also note that transmuting an array will copy (unless the compiler optimizes that out), and transmuting a slice, while not strictly forbidden, should be replaced by pointer casts.Zitvaa
P
3

Starting with Rust 1.55, arrays can be converted between types concisely and safely using the map() method:

let x = [1, 2, 3];
let x_i64 = x.map(i64::from);

This is specific to arrays, and won't work on Vecs.

Photomural answered 31/12, 2022 at 6:26 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.