Я пытаюсь передать право собственности на структуру от «детей» к «геномам» в потоке «create_next_generation», потому что часть геномов должна иметь такое же значение, как у детей, и тогда дети никогда не будут использоваться. Это код процесса, который указывает контекст.
fn create_next_generation<'a>(genomes: &'a mut Vec<Genome>,
children: Vec<Genome>, gene_mutate: f32, individual_mutate: f32, survive_number: usize){
for i in survive_number..children.len(){
genomes[i] = children[i-survive_number]; //<--------error
}
}
fn main() {
let mut genome_list: Vec<Genome> = Vec::new();
.
.
.
let mut children: Vec<Genome> = Vec::new();
.
.
.
create_next_generation(&mut genome_list, children, values.genome_mutation,
values.individual_mutation, values.select_genome)
}
и структура
struct Genome{
dna : Vec<i32>,
eval : f64,
}
Ошибка
error[E0507]: cannot move out of index of `Vec<Genome>`
--> src/main.rs:109:26
|
109 | genomes[i] = children[i-survive_number];
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ move occurs because value has type `Genome`, which does not implement the `Copy` trait
Как я могу решить эту проблему?
Извините, как вы указали, children.len()
> будет бесполезно. Я изменил свой код, спасибо. Затем я попытался использовать .clone()
, но получил ошибку method not found in Genome
. это означает, что структура, которая является типом данных Vec, не имеет метода clone().
В этом случае перемещение запрещено — вы можете перемещать только собственное значение, но значение, которое вы пытаетесь переместить сюда, принадлежит вектору children
. Вы можете заставить это работать с std::mem::take()
(если Genome
реализует Default
), но есть еще более простой способ справиться с этим: Vec::splice()
.
Операция объединения возвращает итератор для диапазона элементов, которые необходимо удалить из вектора, создавая их путем перемещения вместо копирования. То, что вектор изменен, не имеет большого значения, так как он все равно будет уничтожен, но это дает вам простой способ переместить кучу элементов из вектора за одну операцию мутации.
Объединение этого с .enumerate()
дает нам индекс каждого элемента (начиная с 0).
for (i, v) in children.splice(survive_number..).enumerate() {
genomes[i] = v;
}
Неясно, хотите ли вы полностью заменить genomes
этими удаленными элементами, но если это так, то эта операция становится однострочной:
*genomes = children.splice(survive_number..).collect();
Поскольку вы все равно уничтожаете вектор, вы можете даже использовать children.into_iter().skip(survive_number)
вместо children.splice(survive_number..)
в приведенных выше примерах, что приведет к потреблению вектора.
Спасибо за решение. Это сработало хорошо.
Извините, я не понимаю смысла вашего кода. Будет ли
children.len() > i
когда-либо ложным? Если вы пытаетесь укоротить вектор, попробуйте работать сVec::swap_remove
. В противном случае, возможно, вы захотите использоватьchildren[i-survive_number].clone()
.