Как объяснить, как использовать тип данных &str?

Почему второй подход к конкатенации не работает в коде ниже? Есть ли другой способ выполнить конкатенацию в одну строку? Смотрите код примера на Rust ниже:

```rust
fn main() {
    
    let mut s = "x";
    println!("1. {:?}", s);   // "x"

    // Вариант 1:
    let b = s.to_string() + "y";
    s = &b;

    // Вариант 2:
    // s = (s.to_string() + "z").as_str();
    println!("2. {:?}", s);   // "xy"
}
```
  • 21 июля 2024 г. 9:12
Ответы на вопрос 2
Тип данных &str представляет собой ссылку на строку в памяти, который является неизменяемым и имеет фиксированную длину. &str часто используется для передачи строки в функции или методы, чтобы избежать копирования строки.

Почему второй подход не работает: оператор + для строк в Rust принимает два параметра типа String и возвращает новую строку типа String. При попытке преобразовать этот результат в &str с помощью метода as_str() возникает ошибка, так как временное значение созданное во время конкатенации уничтожается после этой операции, что оставляет указатель s на несуществующее в памяти значение.

Для выполнения конкатенации и сохранения результата в переменной типа &str можно использовать методы create_string и as_str, чтобы сохранить временное значение до тех пор, пока s ссылается на него:

```rust
fn main() {
    
    let mut s = "x";
    println!("1. {:?}", s);   // "x"

    // Вариант 1:
    let b = s.to_string() + "y";
    s = &b;

    // Вариант 2:
    let b2 = s.to_string() + "z";
    s = &b2;
    println!("2. {:?}", s);   // "xyz"
}
``` 

Теперь второй подход работает, так как мы сохраняем результат конкатенации в переменной b2 типа String до тех пор, пока s ссылается на это значение.
Для конкатенации строк нужно одно из двух: 
1. Одна из строк должна быть String, а не &str и тогда ты просто добавляешь к ней вторую
2. Ты должнен в процессе конкатенации создавать новый String.

А второй вариант у тебя не работает из-за того что ты дропаешь String, который был создан при конкатенации.

Первый вариант имхо не очень читабельный получился. Лучше попробуй вот так:

fn main() {
    let a = "x";
    println!("1. {:?}", a);   // "x"

    let b = format!("{}y", a);
    println!("2. {:?}", b);    // "xy"
}
Похожие вопросы