如何在不使用时有条件地提供默认引用而不执行不必要的计算?
How can I conditionally provide a default reference without performing unnecessary computation when it isn't used?
我有一些变量通过引用传递到我的函数中。我不需要改变它或转移所有权,我只看它的内容。如果内容处于某种状态,我想用默认值替换该值。
例如,我的函数接受 &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
}
但这给出了错误:
error[E0716]: temporary value dropped while borrowed
--> src/lib.rs:3:16
|
1 | fn accept(mut vec: &Vec<String>) {
| - let's call the lifetime of this reference `'1`
2 | if vec.len() == 0 {
3 | 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
正文中借用了默认值,但您借用的那个值在 [=18= 之外并不存在].那不是我的问题。
有没有更简洁的方法来写出这个模式?
我不认为这是 Is there any way to return a reference to a variable created in a function? 的重复,因为我有一个参考,如果可能的话我想使用 first。我不想取消引用引用或 clone()
它,因为 那会执行不必要的计算 。
我可以同时在变量中存储值或引用吗?
如果您不使用默认矢量,则不必创建它。您只需确保声明在 if
块之外完成。
fn accept(input: &Vec<String>) {
let def;
let vec = if input.is_empty() {
def = vec!["empty".to_string()];
&def
} else {
input
};
// ... do something with `vec`
}
请注意,您不必在每次收到空向量时都构建一个新的默认向量。您可以在第一次发生这种情况时使用 lazy_static or once_cell:
创建它
#[macro_use]
extern crate lazy_static;
fn accept(input: &[String]) {
let vec = if input.is_empty() {
lazy_static! {
static ref DEFAULT: Vec<String> = vec!["empty".to_string()];
}
&DEFAULT
} else {
input
};
// use vec
}
听起来您可能正在寻找 std::borrow::Cow
,具体取决于您将如何使用它。
我有一些变量通过引用传递到我的函数中。我不需要改变它或转移所有权,我只看它的内容。如果内容处于某种状态,我想用默认值替换该值。
例如,我的函数接受 &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
}
但这给出了错误:
error[E0716]: temporary value dropped while borrowed
--> src/lib.rs:3:16
|
1 | fn accept(mut vec: &Vec<String>) {
| - let's call the lifetime of this reference `'1`
2 | if vec.len() == 0 {
3 | 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
正文中借用了默认值,但您借用的那个值在 [=18= 之外并不存在].那不是我的问题。
有没有更简洁的方法来写出这个模式?
我不认为这是 Is there any way to return a reference to a variable created in a function? 的重复,因为我有一个参考,如果可能的话我想使用 first。我不想取消引用引用或 clone()
它,因为 那会执行不必要的计算 。
我可以同时在变量中存储值或引用吗?
如果您不使用默认矢量,则不必创建它。您只需确保声明在 if
块之外完成。
fn accept(input: &Vec<String>) {
let def;
let vec = if input.is_empty() {
def = vec!["empty".to_string()];
&def
} else {
input
};
// ... do something with `vec`
}
请注意,您不必在每次收到空向量时都构建一个新的默认向量。您可以在第一次发生这种情况时使用 lazy_static or once_cell:
创建它#[macro_use]
extern crate lazy_static;
fn accept(input: &[String]) {
let vec = if input.is_empty() {
lazy_static! {
static ref DEFAULT: Vec<String> = vec!["empty".to_string()];
}
&DEFAULT
} else {
input
};
// use vec
}
听起来您可能正在寻找 std::borrow::Cow
,具体取决于您将如何使用它。