这是我的第一段 Rust 代码。我将生命周期参数添加到内部函数只是因为编译器告诉我这样做。虽然我看懂了 Rust 书中的终身解释,但我不可能自己写这个签名。
fn transform_the_expression() {
fn create_formula<'t>(formula: & mut HashMap<& str, &'t str>, input: &'t str, re: Regex)->std::borrow::Cow<'t, str>{
let replacement = re.find(input).unwrap();
formula.insert("1", replacement.as_str());
let rest = re.replace(input, "1");
return rest;
}
let input = "(a+(b*c))";
use regex::Regex;
let re = Regex::new(r"\([\w\d][/*+-^][\w\d]\)").unwrap();
use std::collections::HashMap;
let mut formula = HashMap::new();
let result = create_formula(&mut formula, input, re);
println!("result = {:?}", result);
}
- 为什么签名中的这 3 个地方需要生命周期?
- 为什么其他地方不需要它们?
- 如果编译器不告诉我该做什么,我将如何编写正确的签名?
- 如何识别需要生命周期的参数?
最佳答案
编译器很擅长告诉您何时需要指定生命周期,但不一定擅长让您知道哪些生命周期。
首先,值得一提的是每个引用都有 生命周期;只是有lifetime elision rules这说明如果您不指定它们,编译器将如何填充它们。
回到你的签名:
fn create_formula(formula: & mut HashMap<& str, &str>, input: &str, re: Regex)->std::borrow::Cow<_, str>
第一个绝对需要的生命是Cow<_, str>
中的那个;你需要有一个生命周期来声明这个函数。有两种选择:声明一个,或使用 'static
.在这种情况下,Cow
可能指向 input
的一部分参数,所以你需要把它们绑在一起。首先,需要通过添加 <'t>
来声明新的生命周期。 (任何名称都可以)在函数名称之后,然后将其用于 input
和返回类型:
fn create_formula<'t>(formula: & mut HashMap<& str, &str>, input: &'t str, re: Regex)->std::borrow::Cow<'t, str>
最后,您将借用 input
的部分内容进入HashMap
.如果input
生命周期(我们现在命名为 't
)与 HashMap
无关值,有人可以传入比输入生命周期更长的 HashMap ,从而导致映射中出现悬空指针。所以我们也需要对其进行约束,给出最终版本:
fn create_formula<'t>(formula: & mut HashMap<&str, &'t str>, input: &'t str, re: Regex)->std::borrow::Cow<'t, str>
关键是函数签名需要让编译器相信所有引用的使用都是安全的,这通常意味着你必须在默认情况下明确不同引用参数(和生命周期参数类型)之间的关系(通过省略规则)不要说正确的话。
关于rust - 为什么我需要这些生命周期而不需要其他生命周期,如何知道正确的签名以及如何识别需要生命周期的参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42255868/