2015-03-23 20 views
7

Sono nuovo di Rust e sto cercando di imparare come funzionano i riferimenti. Nel seguente codice quando voglio fare un calcolo su a1 che è i32 Non devo dereferenziarlo. Ma con b1 che è un Box, devo dereferenziarlo.Rust esegue la dereferenziazione automatica di riferimenti di tipo primitivo?

In realtà entrambi i tipi let a2 = a1 * 2; e let a3 = *a1 * 2; si comportano in modo simile. Sembra che il dereferenziamento nei primitivi sia facoltativo OPPURE il compilatore lo sta facendo implicitamente per noi.

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); 

} 

Qualcuno può spiegare questa funzionalità?

risposta

5

Tutti gli operatori aritmetici in Rust vengono implementati sia per i valori primitivi che per i riferimenti ai primitivi su entrambi i lati dell'operatore. Ad esempio, vedere la sezione Implementors di std::ops::Mul, la caratteristica che controlla l'override dell'operatore *.

Vedrai qualcosa di simile:

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 

e così via e così via.

Nel tuo esempio, b1 ha un tipo di &Box<i32> (tipo intero predefinito), e mentre Box implementa molte caratteristiche come passthrough per il suo tipo contenuto (ad esempio impl<T: Read> Read for Box<T>), gli operatori aritmetici non sono tra di loro. Questo è il motivo per cui devi dereferenziare la scatola.

+0

Sì, i valori letterali dei numeri non vincolati sono predefiniti come "i32". –

Problemi correlati