返回&str而不是std::borrow::Cow<'_, str>

6

我想更新类型为&str的变量输入。如何使内部函数返回&str而不是Cow

这可能不是语言的问题,而是正则表达式创建工具的问题。是否有更简单直接的工具可用?

fn transform_the_expression() {

    fn create_formula<'t>(input: &'t str, re: Regex) -> std::borrow::Cow<'t, str> {
        let changed_string = re.replace(input, "1");
        return changed_string;
    }

    let mut input = "(a+(b*c))";
    use regex::Regex;
    let re = Regex::new(r"\([\w\d][/*+-^][\w\d]\)").unwrap();

    println!("input = {:?}", input);
    input = create_formula(input, re);
    println!("input = {:?}", input);
}

为什么呢?你可以通过取消引用 Cow 来获取引用。 - ljedrz
@ljedrz:大概是为了让 input = create_formula(input, re); 能够正常工作。 - Matthieu M.
1个回答

13

不能


Rust的基石是所有权,这是一个你需要理解的概念。

&str 借用但不拥有,它引用了其他人所拥有的一块内存。借用检查器将在编译时确保,被引用的内存块的所有者存在时间比&str更长,否则&str会指向虚无。

在这种情况下,请考虑以下:

  • String 是一只猫
  • &str 是手持设备,运行着这只猫的实时视频(后面跟着一个微型摄像机无人机)

显然,只有当猫存活时,您才能获得其实时视频流,而之后...

而你的问题是问:

如果我杀死了猫,我该如何仍然获得直播?

你不能。


在您的情况下,re.replace创建了一个Cow<'t, str>。 如果查看Cow的定义,您会注意到:

  • 它要么是一个&str
  • 要么是一个String

只有在没有进行替换时,它才是&str,否则它将是String

你无法静态地知道它是哪个,因此你需要考虑“最坏情况”的替代方案:将其视为String

这个String的生存期如何:它取决于您是否从函数中返回它,如果不返回,则无法超出函数的框架。

如果它不超出函数范围,那么您不能拥有超出函数范围的实时视频流。


那么呢?

我的建议是使用String。这将大大简化问题:

fn transform_the_expression() {
    use regex::Regex;

    fn create_formula(input: &str, re: &Regex) -> String {
        re.replace(input, "1").into()
    }

    let mut input = String::from("(a+(b*c))");
    let re = Regex::new(r"\([\w\d][/*+-^][\w\d]\)").unwrap();

    println!("input = {:?}", input);
    input = create_formula(&input, &re);
    println!("input = {:?}", input);
}

谢谢,这非常有帮助。函数into()似乎已经被弃用并替换为into_owned(),至少在borrows.rs中没有包含它。 - J. Dough
2
函数into有点难找,因为它是自动实现的。我建议您查看std::convert::From及其邪恶的孪生兄弟std::convert::Into:对于任何X::from(Y) -> X的实现,您都会自动获得Y::into(self) -> X的实现。 - Matthieu M.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接