Я выполняю упражнения по шорохам и столкнулся с чем-то, чего не до конца понимаю в жизни. Я упрощу код до самой запутанной части.
Эта функция компилируется правильно:
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 (например, это) и понял следующее:
data.to_uppercase()
создаст новую строку.Это понятно, но какая разница между попыткой сохранить его в data
и в newdata
. В обоих случаях я пытаюсь сохранить это временное значение, чтобы избежать его удаления, но один работает, а другой нет.
@trueequalsfalse Да, ты прав!
Второй пример с явным временем жизни:
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
— это новая переменная, поэтому ее время жизни может быть настолько коротким, насколько это необходимо. Поэтому он компилируется.
имеет смысл. О времени жизни в самом типе не подумал. Спасибо!
@Riwen Это неправильно.
data
— изменяемая переменная, содержащая неизменяемую ссылку на строку.