当前位置:  开发笔记 > 后端 > 正文

有没有办法在超出范围之前释放绑定?

如何解决《有没有办法在超出范围之前释放绑定?》经验,为你挑选了1个好方法。

我正在尝试使用正则表达式解析文件:

extern crate regex; // 1.0.1

use regex::Regex;

fn example(
    section_header_pattern: Regex,
    section_name: &str,
    mut line: String,
    mut is_in_right_section: bool,
) {
    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;
        }
    }
}

fn main() {}

......但是编译器会抱怨,因为RegExcaptures()方法有哪些承受了本场比赛的一生借:

error[E0502]: cannot borrow `line` as mutable because it is also borrowed as immutable
  --> src/main.rs:17:13
   |
13 |             .captures(&line)
   |                        ---- immutable borrow occurs here
...
17 |             line.clear();
   |             ^^^^ mutable borrow occurs here
18 |             continue;
19 |         }
   |         - immutable borrow ends here

当我到达时line.clear();,我已经完成了Match并且想要清除缓冲区并移动到文件中的下一行而无需进一步处理.是否有一个好/干净/优雅/惯用的解决方案或我是否需要咬紧牙关并引入随后的'if'块?



1> Shepmaster..:

简答:不.

我已经完成了 Match

你可能是,但编译器不知道.具体来说,生命周期目前与它们所定义的词法范围有关.您正在寻找的特征称为非词汇生命周期.它现在不稳定,但它计划在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
    }
}

推荐阅读
mobiledu2402851373
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有