2015-02-03 4 views
3

Что произойдет, если я заимствую разыменованный указатель?Выполняется ли разыменование по вызову функции?

let a = some object; 
let b = &a; 
let c = &*b; 

Какой у объекта есть c? Производит ли разыменование op временный объект, например возвращаемое значение функции? Как он подчиняется правилам заимствования.

Я также смущен изменчивой семантикой Бокса.

let mut a = Box::new(8us) 
*a = 1; 

Этот код работает отлично, без чего-то вроде Box :: new_mut(). Но

let mut a = &8us; 
*a = 1; 

Ошибка возникает.

ответ

0

Быстрый ответ: Это зависит.

Длинный ответ: продолжайте читать ...

Что произойдет, если я одолжить разыменованный указатель? Если вы проверить LLVM-IR, который генерирует ржавчины, вы можете увидеть все в мелких деталях:

let a = 8us; 
let b = &a; 
let c = &*b; 

получает расширен до

let a; 
// %a = alloca i64 
let b; 
// %b = alloca i64* 
let c; 
// %c = alloca i64* 
a = 8us; 
// store i64 8, i64* %a 
b = &a; 
// store i64* %a, i64** %b 
let tmp = *b; 
// %0 = load i64** %b 
c = tmp; 
// store i64* %0, i64** %c 

теперь LLVM может легко оптимизировать этот материал. Это усложняется после того, как вы реализуете такие черты, как Deref, по вашим собственным типам. Тогда, очевидно, задействован вызов функции, но, скорее всего, оптимизирован снова, так как вы не должны делать сложные вещи в функции deref.

Какой предмет имеет c заимствованный?

c заимствует a

создать ли Разыменование оп временный объект типа возвращаемого значения функции во?

Неа, см.выше

Как это соблюдать правила заимствования.

*b ведет себя так, как если бы это было a. Если вы обратитесь к нему, вы получите ссылку на a.


Чтобы ответить на ваш второй вопрос:

Box принадлежит объект он указывает. Поскольку вы заявили, что ваш Box может быть изменен, вы можете использовать измененную ссылку или любое количество неперемещаемых ссылок на ваш объект. Это означает, что при разыменовании ржавчины Box решает, в зависимости от ситуации, автоматически создавать изменчивую коробку.В случае назначения ваш поле deref'd находится в левой части оператора присваивания, поэтому ржавчина пытается получить изменяемую ссылку на объект.

Если вы даете типы переменных, это становится все более очевидным:

let mut x = Box::new(8us); 
{ 
    let y : &usize = &*x; 
} 
{ 
    let y : &mut usize = &mut *x; 
    *x = 99; // cannot assign to `*x` because it is borrowed 
} 
+1

Ваш ответ неверен: 'c' хранит псевдоним' Ā'. '* b' ** не ** временный стек, это псевдоним rvalue для' a'. Это можно проверить с помощью короткой программы: http://is.gd/CLu5WQ –

+1

«c занимает временный стек, выделенный выделенным объекту». Это меня действительно удивило, и я пошел проверять его. См. [Здесь] (http://is.gd/fmergJ). Это означает, что нет, 'c' заимствует' a', а не копию 'a'. В противном случае это было бы довольно запутанным. –

+0

Я забыл про ссылки rvalue:/ –

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