Ссылки Rust не работают, как в других языках, таких как C / C ++ / Java.Компилятор Rust обеспечивает безопасность памяти во время компиляции и делает это с помощью «средства проверки заимствований».Средство проверки заимствования придерживается набора правил, и опубликованный вами код нарушает одно из них.
Вот прямая цитата из книги Rust, в которой указан этот точный ситуация:
- В любой момент времени вы можете иметь одну изменяемую ссылку или любое количество неизменяемых ссылок.
Сначала вы создаете изменяемуюпеременная s1
, и заимствовать ее как неизменную через s2
.Это нормально, если вы не используете оба из них одновременно .Проблема не возникает здесь, потому что вы еще ничего не сделали со ссылками.Проблема возникает, когда вы заставляете эти две ссылки быть активными одновременно.Это происходит, когда вы получаете доступ к s1
до того, как s2
выйдет из области видимости (это будет после последнего использования).Взгляните на это:
let mut s1 = String::from("hello"); // -- Start of s1 scope --
let s2 = &mut s1; // -- Start of s2 scope --
s2.truncate(2); // s1 may not be used here as
// that breaks the rules
print!("{}", s1); // -- End of s1 scope --
println!("{}", s2); // -- End of s2 scope --
Как видите, из-за структуры вашего кода области действия s1
и s2
должны быть активными одновременно.Если бы вам пришлось поменять местами последние две строки кода, изменив код следующим образом:
let mut s1 = String::from("hello"); // -- Start of s1 scope --
let s2 = &mut s1; // -- Start of s2 scope --
s2.truncate(2); // s1 may not be used here as
// that breaks the rules
println!("{}", s2); // -- End of s2 scope --
print!("{}", s1); // -- End of s1 scope --
Тогда ваш код скомпилировался бы и работал как ожидалось.Причина в том, что, хотя область действия s2
активна, вы вообще не используете s1
.Другими словами, эти вещи происходят в каждой строке приведенного выше кода:
s1
вновь владеет созданным String
s2
с возможностью заимствования String
s2
используется для усечения String
s2
используется для печати String
.Поскольку это последнее использование s2
, после этой строки владение String
возвращается к s1
. s1
используется для печати String
.
Надеюсь, это прояснит ситуацию для вас.
Я бы посоветовал вам уделить время тому, чтобы взглянуть на главу книги Rust "Понимание владения" здесь .Мой совет - прочитать всю книгу, начиная с самого начала.Это даст вам очень хорошее понимание Rust как языка и его экосистемы.