不使用默认引用时,如何有条件地提供默认引用而不执行不必要的计算? [英] How can I conditionally provide a default reference without performing unnecessary computation when it isn't used?

查看:56
本文介绍了不使用默认引用时,如何有条件地提供默认引用而不执行不必要的计算?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一些变量通过引用传递到我的函数中.我不需要对其进行更改或转让所有权,我只需查看其内容即可.如果内容处于某种状态,我想用默认值替换该值.

I have some variable passed into my function by reference. I don't need to mutate it or transfer ownership, I just look at its contents. If the contents are in some state, I want to replace the value with a default value.

例如,我的函数接受& Vec< String> ,并且如果 Vec 为空,则将其替换为 vec!["empty";] :

For instance, my function accepts a &Vec<String> and if the Vec is empty, replace it with 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 会导致与上一个示例相同的错误:

Preventing the mut results in the same error as the previous example:

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 之外提取默认值并引用该值:

The only solution I've come up with is to extract the default value outside the if and reference the value:

fn accept(input: &Vec<String>) {
    let default = vec!["empty".to_string()];
    let vec = if input.len() == 0 {
        &default
    } else {
        input
    };
    // ... do something with `vec`
}

这会导致代码不干净,并且不必要地进行了计算.

This results in less clean code and also unnecessarily doing that computation.

我知道并理解该错误...您正在借用 if 主体内的默认值,但要借用的该值在之外不存在如果.那不是我的问题.

I know and understand the error... you're borrowing the default value inside the body of the if, but that value you're borrowing from doesn't exist outside the if. That's not my question.

有没有更清晰的方式写出这种模式?

Is there any cleaner way to write out this pattern?

我不认为这是

I don't believe this is a duplicate of Is there any way to return a reference to a variable created in a function? because I have a reference I'd like to use first if possible. I don't want to dereference the reference or clone() it because that would perform unnecessary computation.

我可以同时在变量中存储值或引用吗?

Can I store either a value or a reference in a variable at the same time?

推荐答案

如果不使用默认矢量,则不必创建默认矢量.您只需要确保声明是在 if 块之外完成的.

You don't have to create the default vector if you don't use it. You just have to ensure the declaration is done outside the if block.

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

Note that you don't have to build a new default vector every time you receive an empty one. You can create it the first time this happens using 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
}

这篇关于不使用默认引用时,如何有条件地提供默认引用而不执行不必要的计算?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆