2016-03-03 6 views
2

Я борюсь с заемщиком - удивляюсь.Каковы варианты прекращения изменчивого заимствования в Rust?

Хотя я нашел решение, добавив закрытие, мне любопытно, есть ли другие способы прекратить изменчивый заимствование, чтобы следующий оператор мог получить доступ к привязке впоследствии.

Вот что я сделал до сих пор:

let mut canvas: Canvas = Canvas { 
    width: 5, 
    height: 5, 
    array: vec!['x'; 5*5], 
}; 

{ 
    let mut renderer: CanvasRenderer = CanvasRenderer::new(&mut canvas); 

    renderer.render_point('x', 3, 3); 
} 

println!("The Value in the array is: {}", canvas.array[9]); 

Я обернуть закрытия вокруг связывания CanvasRenderer объекта и после того, как мутирует холст и область заканчивается, CanvasRenderer Штампы и мой изменчивый заимствован canvas доступна читать или что угодно.

Это работает, но теперь я хотел бы увидеть другие решения!

Я слышал о drop(stuff), но это не сработало, как я и думал.

+7

Помимо этого: '{...}' is * not * закрытие; это всего лишь блок. –

+0

Я знаю, что закрытие доступно для доступа к следующим связям более высоких областей (например, холст). Пожалуйста, перенаправляйте меня, если я мертв неправильно! – xetra11

+4

@ xetra11 nope, замыкание - это особый вид функции, который может «закрывать» (т. Е. Захватывать, использовать) переменные из охватывающей области (отсюда и название). Вы можете найти больше о них [здесь] (http://doc.rust-lang.org/book/closures.html). То, что вы используете здесь, называется блоками - просто группами операторов. –

ответ

10

Другого выхода нет. Использование блоков способ сделать это. В настоящее время в Rust все записи лексики, то есть они всегда соответствуют некоторому лексическому охвату. Единственный масштаб, который больше, чем один оператор, - это блок, поэтому блоки - это ваш единственный инструмент для ограничения объема займов.

drop() не будет работать по двум причинам: во-первых, поскольку для него потребуется нелексическая область действия, которая не поддерживается в Rust (пока), а во-вторых, она не может быть универсальным инструментом для управления записями: например, он не смог бы закончить неизменный заимствовать просто потому, что неизменяемые ссылки Copy и не могут быть «сброшены». Поэтому, если мы получим нелексические записи, drop()может работать на изменчивые заимствования, но я сомневаюсь, что это будет идиоматический подход.

Сказанное говорит, что в настоящее время внутренняя часть Rust подвергается рефакторингу MIR, специальному промежуточному представлению вашего кода, что должно облегчить, в частности, рассуждения о объемах заимствований. Насколько я помню, вся работа над нелексическими записями была отложена до тех пор, пока МИР не будет готова; впоследствии, я полагаю, таких изменений было бы намного легче сделать.

+0

«потому что неизменяемые ссылки копируются» Вы уверены, что immu ref является копией? Поэтому, если значение, на которое оно ссылается, изменяется, получатель этого immu ref не будет уведомлять или не будет печатать, т.е. новое значение? Потому что у него есть скопированное состояние, а не ссылка на него? Или я снова не сработал с моим мозгом? ;) – xetra11

+0

@ xetra11, если у вас есть неизменяемая ссылка **, нет никакого способа ** изменить данные, на которые он указывает, ни с помощью этой ссылки, ни с помощью каких-либо других средств (кроме «небезопасных», конечно).Более конкретно, если у вас есть неизменяемая ссылка на какую-либо переменную, вы не можете взять изменяемую ссылку на одну и ту же переменную или ее внутренности, и вы не можете напрямую изменять эту переменную, даже если она хранится в слоте 'mut'. Это один из краеугольных камней концепции владения/заимствования Rust, и именно это делает сглаживание неизменных ссылок безопасным. Также обратите внимание, что изменяемые ссылки не копируются. –

+0

Ах да, ты прав. Он говорит, что если есть один изменчивый заимствование, вы не можете иметь значение immut ref для этого значения. Другими словами, будут существовать только mut ref или copys значений ?! (если не небезопасно) – xetra11