Объяснение по ссылкам и займам из книги The Rust - PullRequest
0 голосов
/ 22 июня 2019

Я читаю книгу Rust, и ссылки и заимствования в главе 4 кажутся мне противоречивыми. В Ссылка и заимствование на рисунке 4-5 ниже показано, что s указывает на s1 вместо фактических данных в куче.

fn main() {
    let s1 = String::from("hello");

    let len = calculate_length(&s1);

    println!("The length of '{}' is {}.", s1, len);
}

fn calculate_length(s: &String) -> usize {
    s.len()
}

Figure 4-5: A diagram of &String s pointing at String s1

Но в String Slices диаграмма ясно показывает, что world ссылается на фактические данные, хотя и только на их часть. В нем также говорится, что следующий код «похож на взятие ссылки на всю строку, но с дополнительным битом [0..5]. Вместо ссылки на всю строку, это ссылка на часть строки».

fn main() {
    let s = String::from("hello world");

    let hello = &s[0..5];
    let world = &s[6..11];
}

А вот схема (рисунок 4-6), которая объясняет приведенный выше код: String slice referring to part of a String

Теперь я предполагаю, что мой вопрос заключается в том, почему world не относится к s в случае строковых фрагментов? Я понимаю, что world не может просто указывать на s, потому что тогда он не сможет получить последние 5 букв. Но эти две диаграммы кажутся мне совершенно разными, но все они являются «ссылками». Может кто-нибудь предоставить логичный способ понять это?

Спасибо!

Ответы [ 2 ]

0 голосов
/ 22 июня 2019

Ссылка на строку и фрагмент строки - это разные вещи, поэтому обычно они представляются по-разному.

В большинстве случаев фрагмент строки более полезен, поскольку вы можете ссылаться на подстроки, что делает его более гибким. Обычно параметр функции для чтения некоторых строковых данных должен быть фрагментом строки, а не ссылкой на строку.

Также, вы можете использовать фактический параметр типа &String для среза строки :

Строки реализуют Deref и, таким образом, наследуют все методы. Кроме того, это означает, что вы можете передать строку функция, которая принимает & str с помощью амперсанда (&)

Одна полезная вещь, которую вы не можете сделать со слайсом, - это увеличение размера строки, в этом случае вам нужна изменяемая ссылка на строку. Примером является функция read_line, которая добавляет строковые данные к buf:

pub fn read_line(&self, buf: &mut String) -> Result<usize>

0 голосов
/ 22 июня 2019

Ну что же гарантирует &[mut] String в безопасном контексте?

  • То, что за указателем стоит String, что поддерживает вашу первую диаграмму.

Тогда, что &[mut] str гарантирует в безопасном контексте?

  • Та же идея, что и у String, что за указателем стоит str.Но что это значит?Что на самом деле является str?

Согласно странице документации:

A & str состоит из двух компонентов: указатель на несколько байтов и длина,

Это означает, что &str действительно является указателем на некоторый действительный utf-8 и длину, поэтому на самом деле str - это сами данные, а не String.String можно рассматривать как манипулируемый str.Таким образом, &my_string[..] действительно указатель / ссылка на данные в String.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...