Переназначение переменной вызывает проблемы со сроком службы

Я выполняю упражнения по шорохам и столкнулся с чем-то, чего не до конца понимаю в жизни. Я упрощу код до самой запутанной части.

Эта функция компилируется правильно:

fn string_uppercase(mut data: &String) {
    let newdata: &String = &data.to_uppercase();
}

эта функция не делает

fn string_uppercase(mut data: &String) {
    data = &data.to_uppercase();
}

и показывает следующую ошибку:

error[E0716]: temporary value dropped while borrowed
  --> exercises/06_move_semantics/move_semantics6.rs:25:13
   |
24 | fn string_uppercase(mut data: &String) {
   |                               - let's call the lifetime of this reference `'1`
25 |     data = &data.to_uppercase();
   |     --------^^^^^^^^^^^^^^^^^^^- temporary value is freed at the end of this statement
   |     |       |
   |     |       creates a temporary value which is freed while still in use
   |     assignment requires that borrow lasts for `'1`

error: aborting due to 1 previous error; 1 warning emitted

Я немного пообщался с GPT и SOflow (например, это) и понял следующее:

  1. Вызов функции data.to_uppercase() создаст новую строку.
  2. Это значение создается в выражении и поэтому называется временным, поскольку оно будет удалено, если не будет сохранено в переменной.

Это понятно, но какая разница между попыткой сохранить его в data и в newdata. В обоих случаях я пытаюсь сохранить это временное значение, чтобы избежать его удаления, но один работает, а другой нет.

@Riwen Это неправильно. data — изменяемая переменная, содержащая неизменяемую ссылку на строку.

true equals false 14.04.2024 18:15

@trueequalsfalse Да, ты прав!

Riwen 14.04.2024 18:51
Почему Python в конце концов умрет
Почему Python в конце концов умрет
Последние 20 лет были действительно хорошими для Python. Он прошел путь от "просто языка сценариев" до основного языка, используемого для написания...
0
2
51
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Второй пример с явным временем жизни:

fn string_uppercase<'a>(mut data: &'a String) {
    // data has type &'a String
    data = &data.to_uppercase();
}

data.to_uppercase() создает временную переменную, которая удаляется в конце заключающего оператора. Это значит, что &data.to_uppercase() не может иметь тип &'a String, он живет недостаточно долго. Ключевой факт заключается в том, что тип data сохраняется при переназначении data.

В первом примере newdata — это новая переменная, поэтому ее время жизни может быть настолько коротким, насколько это необходимо. Поэтому он компилируется.

имеет смысл. О времени жизни в самом типе не подумал. Спасибо!

Nicola Pedretti 14.04.2024 20:58

Другие вопросы по теме