Прежде всего, я не спрашиваю, в чем разница между &mut
и ref mut
как таковыми.
Спрашиваю, потому что подумал:
let ref mut a = MyStruct
такой же как
let a = &mut MyStruct
Рассмотрим возврат трейт-объекта из функции. Вы можете вернуть Box<Trait>
или &Trait
. Если вы хотите иметь изменяемый доступ к его методам, возможно ли вернуть &mut Trait
?
Учитывая этот пример:
trait Hello {
fn hello(&mut self);
}
struct English;
struct Spanish;
impl Hello for English {
fn hello(&mut self) {
println!("Hello!");
}
}
impl Hello for Spanish {
fn hello(&mut self) {
println!("Hola!");
}
}
Метод получает изменяемую ссылку для демонстрационных целей.
Это не будет компилироваться:
fn make_hello<'a>() -> &'a mut Hello {
&mut English
}
ни это:
fn make_hello<'a>() -> &'a mut Hello {
let b = &mut English;
b
}
Но это будет компилироваться и работать:
fn make_hello<'a>() -> &'a mut Hello {
let ref mut b = English;
b
}
Моя теория
Этот пример будет работать из коробки с неизменяемыми ссылками (не обязательно присваивать его переменной, просто верните &English
), но не с изменяемыми ссылками. Я думаю, это связано с правилом, что может быть только одна изменяемая ссылка или столько неизменяемых, сколько вы хотите.
В случае неизменяемых ссылок вы создаете объект и заимствуете его как возвращаемое выражение; его ссылка не умрет, потому что она заимствована.
В случае изменяемых ссылок, если вы пытаетесь создать объект и заимствовать его изменяемым образом в качестве возвращаемого выражения, у вас есть две изменяемые ссылки (созданный объект и его изменяемая ссылка). Поскольку у вас не может быть двух изменяемых ссылок на один и тот же объект, он не будет выполнять вторую, поэтому переменная не будет жить достаточно долго. Я думаю, что когда вы пишете let mut ref b = English
и возвращаете b
, вы перемещаете изменяемую ссылку, потому что она была захвачена шаблоном.
Все вышеизложенное — слабая попытка объяснить себе, почему это работает, но у меня нет основ, чтобы это доказать.
Почему это происходит?
Я также запостил этот вопрос на Reddit.
String
включает распределение. - person Shepmaster   schedule 06.12.2017