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

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

问题描述

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

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?

我不相信这是 有什么方法可以返回对在函数中创建的变量的引用? 因为我有一个引用我想使用 first如果可能的话.我不想取消引用引用或 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天全站免登陆