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

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

问题描述

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

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 并且如果 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?

我不认为这是有没有办法返回对在函数中创建的变量的引用? 因为我有一个引用,我想首先使用如果可能的话.我不想取消引用引用或 clone() 因为那样会执行不必​​要的计算.

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_staticonce_cell:

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天全站免登陆