rust - 当依赖项的创建成本很高时该怎么办?

标签 rust rust-crates

我写了一个简单的程序来测试 Cloudflare 的 wirefilter , 这是一个有效的例子。

use wirefilter::{ExecutionContext, Scheme};

lazy_static::lazy_static! {
    static ref SCHEME: Scheme = Scheme! {
        port: Int
    };
}

#[derive(Debug)]
struct MyStruct {
    port: i32,
}

impl MyStruct {
    fn scheme() -> &'static Scheme {
        &SCHEME
    }

    fn execution_context(&self) -> Result<ExecutionContext, failure::Error> {
        let mut ctx = ExecutionContext::new(Self::scheme());
        ctx.set_field_value("port", self.port)?;

        Ok(ctx)
    }
}

fn main() -> Result<(), failure::Error> {
    let data: Vec<MyStruct> = (0..10).map(|i| MyStruct { port: i as i32 }).collect();
    let scheme = MyStruct::scheme();
    let ast = scheme.parse("port in {2 5}")?;
    let filter = ast.compile();

    for i in data
        .iter()
        .filter(|d| filter.execute(&d.execution_context().unwrap()).unwrap())
    {
        println!("{:?}", i);
    }

    Ok(())
}

这将打印:

MyStruct { port: 2 }
MyStruct { port: 5 }

如果我创建向量数据我验证模式后,借用系统将开始提示。

我想在创建该向量之前验证用户输入“port in {2 5}”,这是一项昂贵的操作,有什么办法可以做到吗?

第二个版本的代码是:

use wirefilter::{ExecutionContext, Scheme};

lazy_static::lazy_static! {
    static ref SCHEME: Scheme = Scheme! {
        port: Int
    };
}

#[derive(Debug)]
struct MyStruct {
    port: i32,
}

impl MyStruct {
    fn scheme() -> &'static Scheme {
        &SCHEME
    }

    fn execution_context(&self) -> Result<ExecutionContext, failure::Error> {
        let mut ctx = ExecutionContext::new(Self::scheme());
        ctx.set_field_value("port", self.port)?;

        Ok(ctx)
    }
}

fn main() -> Result<(), failure::Error> {
    let scheme = MyStruct::scheme();
    let ast = scheme.parse("port in {2 5}")?;
    let filter = ast.compile();

    let data: Vec<MyStruct> = (0..10).map(|i| MyStruct { port: i as i32 }).collect();
    for i in data.iter().filter(|d| filter.execute(&d.execution_context().unwrap()).unwrap()) {
        println!("{:?}", i);
    }

    Ok(())
}

这将失败并显示此消息:

error[E0597]: `data` does not live long enough
  --> src/main.rs:33:14
   |
33 |     for i in data.iter().filter(|d| filter.execute(&d.execution_context().unwrap()).unwrap()) {
   |              ^^^^ borrowed value does not live long enough
...
38 | }
   | -
   | |
   | `data` dropped here while still borrowed
   | borrow might be used here, when `filter` is dropped and runs the destructor for type `wirefilter::filter::Filter<'_>`
   |
   = note: values in a scope are dropped in the opposite order they are defined

似乎我可以在创建data之前解析查询,但我无法编译它。

最佳答案

您可以将 data声明与其赋值分开:

let data: Vec<MyStruct>;
let scheme = MyStruct::scheme();
let ast = scheme.parse("port in {2 5}")?;
let filter = ast.compile();
data = (0..10).map(|i| MyStruct { port: i as i32 }).collect();

data 的生命周期与代码的第一个版本相同,而赋值与第二个版本同时发生。

关于rust - 当依赖项的创建成本很高时该怎么办?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55888777/

相关文章:

multidimensional-array - 如何在 &ndarray::Array1<f64> 和 &mut Array1<f64> 之间做减法?

rust - 如何在不发布到 crates.io 的情况下在 Rust 项目之间共享公共(public)代码?

node.js - 如何链接到本地​​ Rust 库? (类似于 npm 链接)

generics - 通过特征而不是结构参数化变量?

rust - 可以在稳定的编译器上控制 Rust 结构对齐吗?

rust - 我可以在稳定的 Rust 上使用编译器插件吗?

installation - 通过 cargo : specified package has no binaries 安装箱子时出错

rust - 为什么使用外部包装箱的功能需要将依赖特征纳入范围?

string - 使用新的 std::fs::File 创建字符串向量

rust - 如何在无限数据流上使用 Wirefilter