How to clone a vector with struct items in Rust.
I've tried to .to_vec() it, but it seems that I can't because I'm using structs.
struct Abc {
id: u32,
name: String
}
let mut vec1: Vec<Abc> = vec![];
let item1 = Abc {
id: 1,
name: String::from("AlgoQ")
}
vec1.push(item1)
let vec2 = vec1.to_vec();
Error:
the trait bound `blabla::Abc: Clone` is not satisfied
the trait `Clone` is not implemented for `blabla::Abc`rustc(E0277)
To clone a Vec the Type inside the Vec also has to implement the Clone trait.
The easiest way to do this is to use the derive macro as seen here.
In your example you'd just have to add #[derive(Clone)] above your Abc struct.
You can do this for objects of structs as you do it for primitives but the struct of the elements of the vector must implement Clone trait to make the vector cloneable.
Exactly as the compiler says
You can use #[derive()] macro easily to implement the trait, unless you don't want to use a custom implementation, as follows
#[derive(Clone)]
struct Abc {
id: u32,
name: String
}
fn main(){
let mut vec1= vec![];
let item1 = Abc {
id: 1,
name: String::from("AlgoQ"),
};
vec1.push(item1);
let vec2 = vec1.clone();
}
Demo
Related
In the Learning Rust by examples website, there is a following code:
use std::fmt::Debug;
trait PrintInOption {
fn print_in_option(self);
}
// Because we would otherwise have to express this as `T: Debug` or
// use another method of indirect approach, this requires a `where` clause:
impl<T> PrintInOption for T where
Option<T>: Debug {
// We want `Option<T>: Debug` as our bound because that is what's
// being printed. Doing otherwise would be using the wrong bound.
fn print_in_option(self) {
println!("{:?}", Some(self));
}
}
fn main() {
let vec = vec![1, 2, 3];
vec.print_in_option();
}
Question:
In println!("{:?}", Some(self));, self is of type Option, what does Some(self) returns in this case? When I ran the code, it prints the vector.
In the line
println!("{:?}", Some(self));
self has type T (not Option). Some() is a constructor of the Option enum, so the expression
Some(self)
has the type Option<T>. In the main() function, T = Vec<i32>, so the type that gets printed is an Option<Vec<i32>>.
I am trying to initialise an array of structs in Rust:
enum Direction {
North,
East,
South,
West,
}
struct RoadPoint {
direction: Direction,
index: i32,
}
// Initialise the array, but failed.
let data = [RoadPoint { direction: Direction::East, index: 1 }; 4];
When I try to compile, the compiler complains that the Copy trait is not implemented:
error[E0277]: the trait bound `main::RoadPoint: std::marker::Copy` is not satisfied
--> src/main.rs:15:16
|
15 | let data = [RoadPoint { direction: Direction::East, index: 1 }; 4];
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `main::RoadPoint`
|
= note: the `Copy` trait is required because the repeated element will be copied
How can the Copy trait be implemented?
You don't have to implement Copy yourself; the compiler can derive it for you:
#[derive(Copy, Clone)]
enum Direction {
North,
East,
South,
West,
}
#[derive(Copy, Clone)]
struct RoadPoint {
direction: Direction,
index: i32,
}
Note that every type that implements Copy must also implement Clone. Clone can also be derived.
Just prepend #[derive(Copy, Clone)] before your enum.
If you really want, you can also
impl Copy for MyEnum {}
The derive-attribute does the same thing under the hood.
I would like to create a new vector that contains objects that implement Trait, from some vectors I already have which contain those objects.
trait Foo {
//
}
struct Bar {
i: i32,
}
struct Baz {
c: char,
}
impl Foo for Bar {
//
}
impl Foo for Baz {
//
}
fn main() {
let v1 = vec![Bar{i: 2},Bar{i: 4}];
let v2 = vec![Baz{c: '2'},Baz{c: '4'}];
let mut v_all: Vec<Box<Foo>> = Vec::new();
v_all.extend(v1.into_iter());
v_all.extend(v2.into_iter());
}
This of course gets me
<anon>:34:11: 34:33 error: type mismatch resolving `<collections::vec::IntoIter<Bar> as core::iter::Iterator>::Item == Box<Foo>`: expected struct Bar, found box
<anon>:34 v_all.extend(v1.into_iter());
How could I achieve this, if possible?
Well, if you have a Bar, and you need a Box<Foo>, then you need to first box the value, then cast it to a trait object, which looks like this:
v_all.extend(v1.into_iter().map(|e| Box::new(e) as Box<Foo>));
v_all.extend(v2.into_iter().map(|e| Box::new(e) as Box<Foo>));
I'm having a lot of fun playing around with Rust having been a C# programmer for a long time but I have a question around reflection. Maybe I don't need reflection in this case but given that Rust is strongly typed I suspect I do (I would definitely need it in good ol' C#, bless its cotton socks).
I have this situation:
use std::collections::HashMap;
fn invoke_an_unknown_function(
hashmap: HashMap<String, String>,
// Something to denote a function I know nothing about goes here
) {
// For each key in the hash map, assign the value
// to the parameter argument whose name is the key
// and then invoke the function
}
How would I do that? I'm guessing I need to pass in some sort of MethodInfo as the second argument to the function and then poke around with that to get the arguments whose name is the key in the hash map and assign the values but I had a look around for the reflection API and found the following pre-Rust 1.0 documentation:
Module std::reflect
Module std::repr
[rust-dev] Reflection system
None of these give me enough to go on to get started. How would I implement the function I describe above?
Traits are the expected way to implement a fair amount of what reflection is (ab)used for elsewhere.
trait SomeInterface {
fn exposed1(&self, a: &str) -> bool;
fn exposed2(&self, b: i32) -> i32;
}
struct Implementation1 {
value: i32,
has_foo: bool,
}
impl SomeInterface for Implementation1 {
fn exposed1(&self, _a: &str) -> bool {
self.has_foo
}
fn exposed2(&self, b: i32) -> i32 {
self.value * b
}
}
fn test_interface(obj: &dyn SomeInterface) {
println!("{}", obj.exposed2(3));
}
fn main() {
let impl1 = Implementation1 {
value: 1,
has_foo: false,
};
test_interface(&impl1);
}
I have roughly the following code:
let val = util::replace(&mut self.some_field[i], self.some_method());
It fails with the following message:
unrelated.rs:61:65: 61:70 error: cannot borrow `*self` as immutable because it is also borrowed as mutable
unrelated.rs:61 let val = util::replace(&mut self.some_field[i], self.some_method());
^~~~~
unrelated.rs:61:36: 61:62 note: second borrow of `*self` occurs here
unrelated.rs:61 let val = util::replace(&mut self.some_field[i], self.some_method());
^~~~~~~~~~~~~~~~~~~~~~~
I can fix this by the following code:
let temp = self.some_method();
let val = util::replace(&mut self.some_field[i], temp);
But why does it fail? The scopes in which mutable and immutable pointers are taken are distinct, they are different expressions. It looks like kind of bug to me, but I just want to make sure that I'm not missing something here.
By introducing temp you've changed computation order: you first computed some_method(), then released self, and then got a mutable reference to some_field of self.
Rust does not allow holding mutable reference along with any other reference (mutable or immutable). See simpler example:
struct Foo {
a: int
}
impl Foo {
fn ff(&self) -> int { 1 }
}
fn fff(a: int, foo: &mut int) { }
fn ggg(foo: &mut int, a: int) { }
fn main() {
let mut foo = Foo { a: 0 };
fff(foo.ff(), &mut foo.a); // this call is valid
ggg(&mut foo.a, foo.ff()); // this is not
}
This is a bug: #6268.
It is because the borrow checker doesn't account for nested method calls properly yet: the nested calls should be equivalent to the code with the temporary (and thus, should be valid).