У меня есть этот шаблон, который время от времени появляется, но я не нашел хорошего способа реализовать его "правильно".
Что это, у меня есть некоторая переменная, переданная в мою функциюпо ссылке. Мне не нужно изменять его, мне не нужно передавать право собственности, я просто смотрю на его содержимое.
Однако, если содержимое находится в каком-либо состоянии, замените значение значением по умолчанию.
Например, скажем, моя функция принимает &Vec<String>
, а если vec пуст, замените его на vec!["empty"]
. Кто-то может реализовать это так:
fn accept(mut vec: &Vec<String>) {
if vec.len() == 0 {
vec = &vec!["empty".to_string()];
}
// ... do something with `vec`, like looping over it
}
Но это дает ошибку:
| fn accept(mut vec: &Vec<String>) {
| - let's call the lifetime of this reference `'1`
| if vec.len() == 0 {
| vec = &vec!["empty".to_string()];
| -------^^^^^^^^^^^^^^^^^^^^^^^^^- temporary value is freed at the end of this statement
| | |
| | creates a temporary which is freed while still in use
| assignment requires that borrow lasts for `'1`
Несколько более «хорошо продуманная» функция может выглядеть следующим образом (предотвращая mut
):
fn accept(input: &Vec<String>) {
let vec = if input.len() == 0 {
&vec!["empty".to_string()]
} else {
input
};
// ... do something with `vec`, like looping over it
}
Однако это все равно приводит к той же ошибке, что и в предыдущем примере.
Единственное решение, которое я нашел, - это извлечь значение по умолчанию за пределы if
и просто сослаться на значение:
fn accept(input: &Vec<String>) {
let default = vec!["empty".to_string()];
let vec = if input.len() == 0 {
&default
} else {
input
};
// ... do something with `vec`
}
Однако это приводит к менее чистому коду и также излишнему выполнению этого вычисления .
Я знаю и понимаю ошибку .. Вы заимствуете значение по умолчанию внутри тела if
, но это значение, от которого вы заимствуете, не существует вне if
. Это не мой вопрос.
Мой вопрос: есть ли более чистый способ выписать этот шаблон?
Я не верю, что это дубликат этого , потому чтов отличие от них, у меня есть ссылка, которую я хотел бы использовать сначала , если это возможно. Я не хочу разыменовывать ссылку или clone()
ее, потому что , которая будет выполнять ненужные вычисления . Отсюда и название моего вопроса: могу ли я одновременно хранить значение или ссылку в переменной? (конечно, вероятно нет, но это то, что я хочу сделать)