简单的回答是:没有。
我受够了
Match
你可能知道,但编译器不知道。具体而言,生命期当前绑定到它们在中定义的词法范围。您正在查找的功能称为
non-lexical lifetimes
.它现在不稳定,但计划在Rust 2018版中启用。
例如:
fn main() {
let mut s = String::from("hello");
let matched = &s[..];
println!("{}", matched);
s.clear();
println!("{}", s);
}
程序员可以告诉我们已经完成了
matched
在我们打印之后,但编译器说借阅将持续到结束
}
解决方案是引入一个范围:
fn main() {
let mut s = String::from("hello");
{
let matched = &s[..];
println!("{}", matched);
}
s.clear();
println!("{}", s);
}
您的情况更加阴险,因为清除字符串的决定与字符串本身的借用值交织在一起。像这样的东西将是我第一个到达的地方:
fn main() {
let mut s = String::from("hello");
let do_clear;
{
let matched = &s[..];
println!("{}", matched);
do_clear = matched.contains("ll");
}
if do_clear {
s.clear();
}
println!("{}", s);
}
然而,您的特定案例可能能够被转换以避免多个
if
/
if let
声明:
let is_in_right_section = section_header_pattern.captures(&line)
.and_then(|c| c.get(1))
.map_or(false, |m| m.as_str() == section_name);
if is_in_right_section {
line.clear();
continue;
}
如果引入新的类型和/或方法,这看起来不会太糟糕。作为奖励,有一个地方
Regex
生活:
struct Section(Regex);
impl Section {
fn is(&self, s: &str, section: &str) -> bool {
self.0
.captures(s)
.and_then(|c| c.get(1))
.map_or(false, |m| m.as_str() == section)
}
}
// ----
if section.is(&line, section_name) {
line.clear();
continue;
}
启用NLL时,原始代码按原样工作:
#![feature(nll)]
extern crate regex; // 1.0.1
use regex::Regex;
fn main() {
let section_header_pattern = Regex::new(".").unwrap();
let section_name = "";
let mut line = String::new();
let mut is_in_right_section = false;
loop {
if let Some(m) = section_header_pattern
.captures(&line)
.and_then(|c| c.get(1))
{
is_in_right_section = m.as_str().eq(section_name);
line.clear();
continue;
}
return; // I don't really want to loop
}
}