2015-03-23 6 views
7

Ich bin neu in Rust und versuche zu lernen, wie Referenzen funktionieren. Im folgenden Code, wenn ich eine Berechnung auf a1 machen möchte, die i32 ist, muss ich es nicht dereferenzieren. Aber mit b1, die eine Box ist, muss ich es dereferenzieren.Veraltet Rust automatisch primitive Typreferenzen?

Tatsächlich verhalten sich sowohl let a2 = a1 * 2; als auch let a3 = *a1 * 2; ähnlich. Es sieht so aus, als ob die Dereferenzierung in Primitiven optional ist ODER der Compiler das implizit für uns erledigt.

fn main(){ 
    let a = 5; 
    let b = Box::new(10); 
    let a1 = &a; 
    let b1 = &b; 

    println!("{} {}", a1, b1); 

    let a2 = a1 * 2; 
    let b2 = (**b1) * 10; 
    let a3 = *a1 * 2; 

    println!("{} {} {}", a2, a3, b2); 

} 

Kann jemand bitte diese Funktionalität erklären?

Antwort

5

Alle arithmetischen Operatoren in Rust werden sowohl für primitive Werte als auch für Verweise auf Primitive auf beiden Seiten des Operators implementiert. Siehe zum Beispiel den Abschnitt Implementors von std::ops::Mul, der die Übersteuerung des Operators * steuert.

Sie werden sehen, so etwas wie:

impl Mul<i32> for i32 
impl<'a> Mul<i32> for &'a i32 
impl<'a> Mul<&'a i32> for i32 
impl<'a, 'b> Mul<&'a i32> for &'b i32 

und so weiter und so weiter.

In Ihrem Beispiel b1 eine Art &Box<i32> hat (der Standard-Integer-Typen), und während Box implementiert viele Züge als Pass-Through für die darin enthaltenen Art (z impl<T: Read> Read for Box<T>) sind die arithmetischen Operatoren nicht unter ihnen. Deshalb muss die Box dereferenziert werden.

+0

Ja, unbeschränkte Ganzzahlliterale standardmäßig auf 'i32'. –