2016-03-31 4 views
10

Несмотря на тщательное чтение документации, я довольно запутался в значении символов & и * в Rust и, в более общем плане, о том, что такое ссылка Rust в точку.Значение амперсанда '&' и звездочек '*' символов в Rust

В этом примере, это, кажется, похож на ссылки C++ (то есть адрес, который автоматически разыменовываются при использовании):

fn main() { 
    let c: i32 = 5; 
    let rc = &c; 
    let next = rc + 1; 
    println!("{}", next); // 6 
} 

Однако следующий код работает точно так же:

fn main() { 
    let c: i32 = 5; 
    let rc = &c; 
    let next = *rc + 1; 
    println!("{}", next); // 6 
} 

Использование * для разыменования ссылки в C++ неверно. Поэтому я хотел бы понять, почему это правильно в Rust.

Мое понимание до сих пор, является то, что, вставив * перед ржавчиной ссылочных разыменовывает него, но * неявно вставляется в любом случае, так что вам не нужно, чтобы добавить его (в то время как в C++, он неявно вставляется и если вы вставьте его, вы получите ошибку компиляции).

Однако, что-то вроде этого не компилируется:

fn main() { 
    let mut c: i32 = 5; 
    let mut next: i32 = 0; 
    { 
     let rc = &mut c; 
     next = rc + 1; 
    } 
    println!("{}", next); 
} 
<anon>:6:16: 6:18 error: binary operation `+` cannot be applied to type `&mut i32` [E0369] 
<anon>:6   next = rc + 1; 
         ^~ 
<anon>:6:16: 6:18 help: see the detailed explanation for E0369 
<anon>:6:16: 6:18 note: an implementation of `std::ops::Add` might be missing for `&mut i32` 
<anon>:6   next = rc + 1; 

Но это работает:

fn main() { 
    let mut c: i32 = 5; 
    let mut next: i32 = 0; 
    { 
     let rc = &mut c; 
     next = *rc + 1; 
    } 
    println!("{}", next); // 6 
} 

кажется, что неявное разыменование (а-ля C++) является правильным для неизменных ссылок , но не для изменяемых ссылок. Почему это?

ответ

12

Использование * для разыменования ссылки на C++ неверно. Поэтому я хотел бы понять, почему это правильно в Rust.

Ссылка на C++ не совпадает с ссылкой в ​​Rust. Ссылки Rust намного ближе (в использовании, а не в семантике) к указателям C++. Что касается представления памяти, ссылки Rust часто являются всего лишь одним указателем, в то время как ссылки C++ должны быть альтернативными именами одного и того же объекта (и, следовательно, не имеют представления памяти).

Разница между указателями C++ и ссылками Rust заключается в том, что ссылки Rust никогда не являются NULL, никогда неинициализированными и никогда не свисающими.


Add черта реализован (см в нижней части страницы док) для следующих пар и всех других числовых примитивов:

  • &i32 + i32
  • i32 + &i32
  • &i32 + &i32

Это просто удобная вещь, реализованная разработчиками std-lib. Компилятор может понять, что &mut i32 может использоваться везде, где может использоваться &i32, но это не работает (пока?) Для дженериков, поэтому СТД Пб разработчикам потребуется также реализовать Add черты для следующих комбинаций (и те, для всех примитивов):

  • &mut i32 + i32
  • i32 + &mut i32
  • &mut i32 + &mut i32
  • &mut i32 + &i32
  • &i32 + &mut i32

Как вы можете видеть, это может стать совершенно из-под контроля. Я уверен, что это исчезнет в будущем. До тех пор обратите внимание, что довольно редко заканчивается &mut i32 и пытается использовать его в математическом выражении.

+1

Спасибо, я понимаю. На самом деле, я думал, что это может быть что-то вроде этого, но я отклонил эту мысль, считая, что было бы очень странно определять сумму целого числа с таким адресом целого. Возможно, в документе должно быть подчеркнуто, что ссылки Rust следует рассматривать как адреса и не следует путать с ссылками на C++. Еще раз спасибо за подробное объяснение. –

3

Из документов для std::ops::Add:

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

кажется бинарный оператор + для чисел реализуется для комбинаций общих (но не изменяемых) ссылки операндов и принадлежащих версий операндов. Это не имеет никакого отношения к автоматическому разыменованию.

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

  • Нет связанных вопросов^_^