2015-08-26 8 views
6

Ich lese die Rust 101 tutorial, wo der Autor über gemeinsame Borrowing mit dem Beispiel einer Vec Objekt an eine Funktion übergeben spricht. Unten ist ein leicht angepasster MWE von dem, was das Tutorial lehrt. Der interessante Teil ist v.iter() in vec_min. Der Autor schreibt:Unterschied zwischen iter() und in_iter() auf einem gemeinsamen, geliehenen Vec?

Diesmal fordern wir explizit einen Iterator für den Vektor v. Die Methode iter borgt den Vektor, an dem sie arbeitet, und stellt gemeinsame Ausleihen der Elemente bereit.

Aber was passiert, wenn ich eine for ... in ... Konstruktion auf einem Objekt verwende, das geteilt wird? Gemäß this blog post verwendet diese implizite for-Schleife into_iter() und übernimmt den Besitz von v. Aber es kann nicht wirklich Besitz von der v in dieser Funktion übernehmen, da es nur von Anfang an geliehen hat, oder?

Kann mir jemand den Unterschied zwischen into_iter() und iter() erklären, der auf ein geliehenes Objekt angewendet wurde?

enum NumberOrNothing { 
    Number(i32), 
    Nothing, 
} 
use self::NumberOrNothing::{Number,Nothing}; 

impl NumberOrNothing { 
    fn print(self) { 
     match self { 
      Nothing => println!("The number is: <nothing>"), 
      Number(n) => println!("The number is: {}", n), 
     }; 
    } 
} 

fn vec_min(v: &Vec<i32>) -> NumberOrNothing { 
    fn min_i32(a: i32, b: i32) -> i32 { 
     if a < b {a} else {b} 
    } 

    let mut min = Nothing; 
    for e in v.iter() { 
    //Alternatively implicitly and with *e replaced by e: 
    //for e in v { 
     min = Number(match min { 
      Nothing => *e, 
      Number(n) => min_i32(n, *e), 
     }); 
    } 
    min 
} 

pub fn main() { 
    let vec = vec![18,5,7,2,9,27]; 
    let foo = Nothing; 
    let min = vec_min(&vec); 
    let min = vec_min(&vec); 
    min.print(); 
} 

Antwort

9

Aber es kann die v in dieser Funktion nicht wirklich in Besitz nehmen, da sie es nur mit

beginnen geliehen hat es absolut Eigentum an v nehmen kann, denn das ist ein ist &Vec. Beachten Sie die genaue Semantik hier - Sie übernehmen das Eigentum der Referenz, nicht des genannten Artikels.

Wenn Sie die implementors of IntoIterator Check-out, können Sie finden:

impl<'a, T> IntoIterator for &'a Vec<T> 

Und die source for that:

impl<'a, T> IntoIterator for &'a Vec<T> { 
    fn into_iter(self) -> slice::Iter<'a, T> { 
     self.iter() 
    } 
} 

Überraschung - es nennt iter! Die Antwort auf Ihre Frage lautet also: Es gibt keinen Unterschied.

+3

Richtig, das ist großartig, vielen Dank! Ich war auch verwirrt über 'into_iter()' kann sowohl auf '& Vec' und' Vec' arbeiten, aber die Quelle, die Sie verweisen, erklärt es: Es gibt einen Implementierer für 'Vec ' sowie für '& 'a Vec ' und '& 'ein mut Vec '. Sehr coole Sachen! :) – mSSM