This question already has answers here:
Initialize a large, fixed-size array with non-Copy types
(8 answers)
Closed 1 year ago.
I now why the error below happens, you cannot copy a Box, because it's a "unique_ptr".
fn main() {
let array: [Option<Box<u32>>; 3] = [None; 3];
}
https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=0da6902c0157df3015bc85a621079e18
I know I could do [None, None, None], but what about giant arrays? Is there a way to initialize them with None?
error[E0277]: the trait bound `Option<Box<u32>>: Copy` is not satisfied
--> src/main.rs:2:40
|
2 | let array: [Option<Box<u32>>; 3] = [None; 3];
| ^^^^^^^^^ the trait `Copy` is not implemented for `Option<Box<u32>>`
|
= help: the following implementations were found:
<Option<T> as Copy>
= note: the `Copy` trait is required because the repeated element will be copied
For arrays with a size not greater than 32 you could use:
let array: [Option<Box<u32>>; 32] = Default::default();
For even bigger arrays I would recommend using a crate like this or creating a simple macro.
I recommend reading this article: https://www.joshmcguigan.com/blog/array-initialization-rust/
Related
This question already has an answer here:
How do I sort an array?
(1 answer)
Closed 6 days ago.
I tried to write a program that does the following thing: take all suffixes of a given string s, then sort these suffixes with dictionary order.
here is my code:
let mut sorted = (0..s.len())
.map(|i| (i, &s[i..s.len()]))
.collect::<Vec<(usize, &str)>>()
.sort_by_key(|k| k.1);
for elem in sorted {
println!("{} {}", elem.0, elem.1);
}
and rust compiler gives an error:
error[E0277]: `()` is not an iterator
--> src/lt05.rs:7:17
|
7 | for elem in sorted {
| ^^^^^^ `()` is not an iterator
|
= help: the trait `Iterator` is not implemented for `()`
= note: required for `()` to implement `IntoIterator`
Could anyone please explain what is wrong in this code?
Vec::sort_by_key sorts a vector in place and returns (). So in your code sorted ends up being assigned (), the unit type which you can't iterate over.
To fix this you can simply sort the vector after you've constructed it by moving the call to sort_by_key into a separate statement and then iterate over the sorted vector. See example below. Here is a Rust Playground which does this.
fn main() {
let s = "thisisatest";
let mut sorted =
(0..s.len())
.map(|i| (i, &s[i..s.len()]))
.collect::<Vec<(usize, &str)>>();
sorted.sort_by_key(|k| k.1);
for elem in sorted {
println!("{} {}", elem.0, elem.1);
}
}
Output
6 atest
8 est
1 hisisatest
4 isatest
2 isisatest
5 satest
3 sisatest
9 st
10 t
7 test
0 thisisatest
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
I'm trying to copy a slice from a raw pointer into a new slice ss:
pub fn receive(&mut self, data: *const u8, len: usize) {
let s = unsafe{slice::from_raw_parts(data, len)};
let mut ss = [0, len];
ss.copy_from_slice(s);
self.received.lock().unwrap().push_back(ss);
}
but I'm having trouble creating this new slice. I tried to give the lenght len so it's compatible with slice s but I do not understand what's happening
I'm trying to copy a slice from a raw pointer into a new slice ss:
There is no such thing as a "new slice", a slice always points to memory from something else. If you want to copy an existing slice to a new location, you will need to allocate the data for that location, e.g. using a Vec:
let mut ss = vec![0; len];
ss.copy_from_slice(s);
However, since you already have a slice (s) and the push_back method of self.received accepts a slice, why not avoid the copying and simply call self.received.lock().unwrap().push_back(s)?
Providing error messages is usually helpful to help diagnose issues. Providing an immediately usable reproduction of the issue (e.g. something on the playground) is also useful.
Anyway cutting down on the things we can't know and don't care about in your function we get this:
use std::slice;
fn receive(data: *const u8, len: usize) {
let s = unsafe{slice::from_raw_parts(data, len)};
let mut ss = [0, len];
ss.copy_from_slice(s);
}
Compiling yields the following:
error[E0308]: mismatched types
--> src/lib.rs:6:28
|
6 | ss.copy_from_slice(s);
| ^ expected `usize`, found `u8`
|
= note: expected reference `&[usize]`
found reference `&[u8]`
So ss is a &[usize] instead of an &[u8]. Weird. Let's explicitly type ss as an &[u8] to try and force it then:
error[E0308]: mismatched types
--> src/lib.rs:5:25
|
5 | let mut ss: &[u8] = [0, len];
| ----- ^^^^^^^^ expected `&[u8]`, found array `[usize; 2]`
| |
| expected due to this
Well there's the issue: [0, len] is not a slice. It's an array of length 2 containing the two elements 0 and whatever len is (and since len is usize it's an [usize;2]. A slice literal is &[], and neither arrays nor slice literals can take a runtime length, the length needs to be known at compile-time.
And even if you do make it a slice, you probably won't be able to push it into received, because the slice just refers to data local to the function, it won't be able to escape.
You might want a Vec.
This question already has answers here:
What does it mean to pass in a vector into a `for` loop versus a reference to a vector?
(1 answer)
How can I solve "use of moved value" and "which does not implement the `Copy` trait"?
(1 answer)
What do I have to do to solve a "use of moved value" error?
(3 answers)
What does "cannot move out of index of" mean?
(2 answers)
Closed 2 years ago.
This doesn't work:
let vectors = vec![1, 2, 3, 4, 5, 6, 7];
for i in vectors {
println!("Element is {}", i);
}
let largest = vectors[0];
Error message:
error[E0382]: borrow of moved value: `vectors`
--> src/main.rs:8:19
|
2 | let vectors = vec![1, 2, 3, 4, 5, 6, 7];
| ------- move occurs because `vectors` has type `std::vec::Vec<i32>`, which does not implement the `Copy` trait
3 |
4 | for i in vectors {
| -------
| |
| value moved here
| help: consider borrowing to avoid moving into the for loop: `&vectors`
...
8 | let largest = vectors[0];
| ^^^^^^^ value borrowed here after move
The vector has been moved into the loop. Its ownership — and that of its individual elements — has been transferred there permanently.
But this works:
let largest = vectors[0];
let largest2 = vectors[0];
I don't know why; the vectors[0] value should have been moved to largest and largest2 should then fail, but it didn't.
When you use vectors inside a for..in loop, Rust will call the IntoIterator::into_iter trait method of the Vec, which takes ownership of self. Therefore you cannot use vectors afterwards.
use std::iter::IntoIterator;
// these are equivalent
for i in vectors { /* ... */ }
for i in IntoIterator::into_iter(vectors) { /* ... */ }
The index operator, on the other hands, calls the Index::index trait method of the Vec, which takes self by reference. Additionally, it automatically dereferences the value, so that if the items inside the vector implement Copy, they will be copied out of the vector instead of borrowed (you need to explicitly borrow if you want a reference):
use std::ops::Index;
// these are equivalent
let x = vectors[0];
let x = *Index::index(&vectors, 0);
// these are equivalent
let x = &vectors[0];
let x = Index::index(&vectors, 0);
The type of the values (probably i32) in your Vec implement the Copy trait, which means that they do not get moved out when indexing the vector, they get copied instead.
A Vec of such Copy types still doesn't implement Copy itself, so it gets moved into the loop. You can avoid this e.g. by writing
for i in vectors.iter() {
println!("Element is {}", *i);
}
The dereference (*) gives you an owned value like you'd get in your original code sample. It isn't necessary for println!, but might be necessary for other uses.
This question already has an answer here:
How to filter a vector of custom structs?
(1 answer)
Closed 4 years ago.
I have a vector and trying to create a new vector by filtering. It does not work and I don't know why:
fn example(data: Vec<f64>, missing_value: f64) {
let dude = data
.iter()
.filter(|&x| *x != missing_value)
.collect::<Vec<f64>>();
}
error[E0277]: a collection of type `std::vec::Vec<f64>` cannot be built from an iterator over elements of type `&f64`
--> src/lib.rs:5:10
|
5 | .collect::<Vec<f64>>();
| ^^^^^^^ a collection of type `std::vec::Vec<f64>` cannot be built from `std::iter::Iterator<Item=&f64>`
|
= help: the trait `std::iter::FromIterator<&f64>` is not implemented for `std::vec::Vec<f64>`
There is a single implementation of FromIterator for Vec, and this implementation collects values of T from the same type T, i.e., it is not possible to convert T into an arbitrary type U and collect its elements at the same time.
In your case, you want to collect an iterator of &f64 into a vector of f64, therefore, you need to convert by cloning/copying and then collect.
self.data.iter().filter(|&&x| x != self.missing_value).cloned().collect::<Vec<f64>>();
If you have ownership of the vector, it is possible to iterate over f64 instead of &f64 by using into_iter.
self.data.into_iter().filter(|&x| x != self.missing_value).collect::<Vec<f64>>();
I am trying to slice a vector and print it simultaneously in Rust. This is my code:
fn main() {
let a = vec![1, 2, 3, 4];
println!("{:?}", a[1..2]);
}
Error:
error[E0277]: the trait bound `[{integer}]: std::marker::Sized` is not satisfied
--> src/main.rs:6:5
|
6 | println!("{:?}", a[1..3]);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ trait `[{integer}]: std::marker::Sized` not satisfied
|
= note: `[{integer}]` does not have a constant size known at compile-time
= note: required by `std::fmt::ArgumentV1::new`
= note: this error originates in a macro outside of the current crate
How do I print this sliced vector?
You need to use a reference; it worked for me in Rust 1.13.
println!("{:?}", &a[1..3]);