2017-01-08 4 views
1

Ich stoße auf ein Problem mit Lebenszeiten im Rost, dass ich Probleme habe herauszufinden. Ich habe eine Menge Optimierungen an der Unterseite versucht, aber ich führe ständig neue Fehler ein. Ich möchte, dass der Index ein Vektorobjekt zurückgibt.Rust lifetime - Variable lebt nicht lange genug Fehler

ich habe:

struct Matrix<T> { 
    num_rows: i32, 
    num_cols: i32, 
    data: Vec<T> 
} 

struct Vector<T> { 
    data: Vec<T> 
} 

Und ich versuche

impl<T: Clone> Index<usize> for Matrix<T> { 
    type Output = Vector<T>; 

    fn index(&self, i: usize) -> &Vector<T> { 
     let index = i as i32; 
     let start = (index * &self.num_cols) as usize; 
     let end = (((index + 1) * &self.num_cols) - 1) as usize; 
     let data_slice = &self.data[start..end]; 
     let data = data_slice.to_vec(); 
     let vector_temp = Vector::<T>::new(data); 
     return &vector_temp; 
    } 
} 

zu tun, aber ich bin immer

error: `vector_temp` does not live long enough 
    --> src\main.rs:45:17 
    | 
45 |   return &vector_temp; 
    |     ^^^^^^^^^^^ does not live long enough 
46 |  } 
    |  - borrowed value only lives until here 
    | 
note: borrowed value must be valid for the anonymous lifetime #1 defined on  the block at 38:44... 
    --> src\main.rs:38:45 
    | 
38 |  fn index(&self, i: usize) -> &Vector<T> { 
    |           ^

error: aborting due to previous error 

error: Could not compile `hello_world`. 

habe ich nicht voll grokked Leben in Rost noch Ich habe gehofft, dass mir jemand helfen könnte. Vielen Dank!

Antwort

3

Sie versuchen, einen Verweis auf ein Objekt zurückzugeben, das nach dem Ende der Funktion zerstört wird. vector_temp wird nicht mehr existieren, sobald index zurückkehrt und die Rückgabe eines Verweises darauf illegal ist (weil dieser Verweis auf nichts verweisen würde).

Was Sie tun möchten, ist die Scheibe zurückkehren Sie erstellen und lassen Sie den Anrufer entscheiden, was damit zu tun:

impl<T: Clone> Index<usize> for Matrix<T> { 
    type Output = [T]; 

    fn index(&self, i: usize) -> &[T] { 
     let index = i as i32; 
     let start = (index * &self.num_cols) as usize; 
     let end = (((index + 1) * &self.num_cols) - 1) as usize; 

     &self.data[start..end] 
    } 
} 

Sie können dann der Anrufer tun, was Sie in Ihrer ursprünglichen Implementierung tat :

let m1 = Matrix { ... }; 
let owned_vector = m1[index_here].to_owned(); 

I am not 100% sure where you go from here, ich bin mir nicht sicher gegeben, wie viel dies weiter zu Sie nehmen werden. Die Rückgabe des ungeschnittenen Slices kann zu Problemen führen. Wenn Sie also Ihren spezifischen Anwendungsfall nicht kennen, bin ich mir nicht sicher, ob es einen besseren Weg für Sie gibt.

Hoffentlich hilft dies jedoch mit Ihrem unmittelbaren Problem.

Verwandte Themen