2016-11-02 2 views
-2

Я пытаюсь написать реализацию кД-дерева, но я получаю ошибку cannot move out of borrowed content.Я не понимаю, как заимствование работает

Это мой KDTree структура

pub struct KDTree { 
    pub bounding_box: Aabb, 
    pub axis: Option<Axis>, 
    left: Option<Box<KDTree>>, 
    right: Option<Box<KDTree>>, 
    pub objects: Option<Vec<Box<Geometry>>>, 
} 

Этот метод, однако, , выдает эту ошибку.

pub fn direct_samples(&self) -> Vec<u32> { 
    assert!(self.objects.is_some()); 
    let mut direct_samples = Vec::new(); 
    for (i, object) in self.objects 
     .expect("Expected tree to have objects") 
     .iter() 
     .enumerate() { 
     if object.material().emittance > 0f32 { 
      direct_samples.push(i as u32); 
     } 
    } 
    if self.left.is_some() { 
     direct_samples.extend(self.left.unwrap().direct_samples()); 
    } 
    if self.right.is_some() { 
     direct_samples.extend(self.right.unwrap().direct_samples()); 
    } 
    direct_samples 
} 

Я понимаю, что если изменить параметр на self вместо &self, он должен работать, но потом, когда я звоню, он дает ошибку use of moved value.

pub fn from_objects(objects: Vec<Box<Geometry>>) -> Scene { 
    let tree = KDTree::from_objects(objects); 

    Scene { 
     camera: Camera::new(), 
     objects: tree, 
     direct_samples: tree.direct_samples(), 
    } 
} 

Мне нужно реализовать Copy Do на моем KDTree? Не будет ли это использовать много процессора/памяти для копирования всего?

+0

Помимо этого: 'Опция ' кажется подозрительной, 'Vec' уже может быть пустым, поэтому перенос ее в« Option », который вы затем утверждаете, не должен существовать, кажется довольно бесполезным. Даже если 'Нет' и' Некоторые (empty_vec) 'действительно означают что-то другое, это довольно запутанное различие. – delnan

ответ

5

Причина, по которой ваш код требует права собственности на KDTree, заключается в том, что вы вызываете Option::expect и Option::unwrap. Документы для них можно найти here.

impl<T> Option<T> { 
    fn unwrap(self) -> T { 
     ... 
    } 
} 

Так что, когда вы звоните развертку (или ожидать) компилятор справедливо жалуется, что вы принимаете элементы вашей структуры по значению. Чтобы исправить это, используйте Option::as_refmethod.

impl<T> Option<T> { 
    fn as_ref(&self) -> Option<&T> { 
     ... 
    } 
} 

Это превратит ссылку на опцию в необязательную ссылку, которая не требует права собственности. Вы можете видеть это в сигнатуре функции - она ​​принимает &self, а не self.

pub fn direct_samples(&self) -> Vec<u32> { 
    assert!(self.objects.is_some()); 
    let mut direct_samples = Vec::new(); 
    for (i, object) in self.objects.as_ref() 
     .expect("Expected tree to have objects") 
     .iter() 
     .enumerate() { 
     if object.material().emittance > 0f32 { 
      direct_samples.push(i as u32); 
     } 
    } 
    if self.left.is_some() { 
     direct_samples.extend(self.left.as_ref().unwrap().direct_samples()); 
    } 
    if self.right.is_some() { 
     direct_samples.extend(self.right.as_ref().unwrap().direct_samples()); 
    } 
    direct_samples 
} 

Мне нужно реализовать копию на мой KDTree ли? Не будет ли это использовать много процессора/памяти для копирования всего?

Вы не можете реализовать Copy на вашем KDTree, поскольку она содержит кучного распределяемой памяти (ящики) - Copy означает, что ваш тип может быть скопирован только путем копирования его байт, но это не может произойти без нарушения единой собственности в этом случае.

Смежные вопросы