Hi!
let ar1: [u8; 3] = [1,2,3];
let mut r: [u8; 2] = Default::default();
r.copy_from_slice(&v[..2]);
Is it possible to build new array without default and copy?
Something like
let r = [u8; 2]::from_slice(&v[..2]);
Hi!
let ar1: [u8; 3] = [1,2,3];
let mut r: [u8; 2] = Default::default();
r.copy_from_slice(&v[..2]);
Is it possible to build new array without default and copy?
Something like
let r = [u8; 2]::from_slice(&v[..2]);
There are some implementations of TryFrom
for slices and arrays.
When the type in the array is Copy
you can convert a slice directly into an array. For non-copy types, you can convert a slice to a reference to an array.
fn main() {
let slice: &[u8] = &[1, 2, 3, 4];
let arr = <[u8; 4]>::try_from(slice);
let strings: &[String] = &["one".into(), "two".into()];
let string_arr = <&[String; 2]>::try_from(strings);
println!("{arr:?}\n{string_arr:?}");
}
Since there’s a blanket impl of TryInto
on TryFrom
you can also rephrase it like
fn main() {
let slice: &[u8] = &[1, 2, 3, 4];
let arr: Result<[u8; 4], _> = slice.try_into();
let strings: &[String] = &["one".into(), "two".into()];
let string_arr: Result<&[String; 2], _> = strings.try_into();
println!("{arr:?}\n{string_arr:?}");
}
Which may be easier in some contexts
Looks easier but i'm surprised of rust cant to create array with copy of another without "try..."
Well a slice doesn't have a statically known size, so if the slice is too short it's really important that it not just silently hand you uninitialized memory. Hence the Result.
These implementations actually require that the size of the slice is exactly the same to help catch bugs more easily. (e.g. let arr: Result<[u8; 2], _> = slice.try_into();
returns an error)
arr[0..2]
Doesn't statically known size?
Yes, because arr[a..b]
does not require the endpoints a
and b
to be const
. Rust cannot infer anything about the size of a slice during compilation. Even if you use int literals, which are const
.
It's statically known enough for the optimizer to remove code which handles incorrect size, but it's not statically known enough to have Sized
type.
It's still !Sized
, just its current size happens to always be 3.
Here's one way:
let ar1: [u8; 3] = [1,2,3];
let r: [u8; 2] = std::array::from_fn(|i| ar1[i]);
Compiles down to essentially nothing, too: https://rust.godbolt.org/z/9znjozM38.
This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.