gpt4 book ai didi

memory-leaks - 使用此代码是否有避免 `Box::leak` 的惯用方法?

转载 作者:行者123 更新时间:2023-11-29 08:34:22 28 4
gpt4 key购买 nike

随着我继续学习 Rust,我正在从事一个涉及广泛使用谓词函数的项目。我决定用 Rust 闭包实现这些谓词,例如:

type Predicate = Box<Fn(&Form) -> bool> .

我的程序使用应用于这些谓词的 bool 逻辑。例如,and以及or应用于这些谓词的值。我使用 Box::leak 完成了这项工作:

struct Form {
name: String,
}

fn and(a: Option<Predicate>, b: Option<Predicate>) -> Option<Predicate> {
if a.is_none() {
return b;
} else if b.is_none() {
return a;
} else {
let a = Box::leak(a.unwrap());
let b = Box::leak(b.unwrap());
return Some(Box::new(move |form: &Form| a(form) && b(form)));
}
}

虽然这似乎如我所愿,Box::leak似乎不理想。我对 std::rc::Rc 了解不够和 std::cell::RefCell知道这些是否可以帮助我避免 Box::leak此处 — 使用它们可能需要对我的代码进行重大重组,但我想至少了解这里的惯用方法可能是什么。

有没有办法在保持相同功能的同时避免泄漏?

这是 the complete example :

struct Form {
name: String,
}

type Predicate = Box<Fn(&Form) -> bool>;

struct Foo {
predicates: Vec<Predicate>,
}

impl Foo {
fn and(a: Option<Predicate>, b: Option<Predicate>) -> Option<Predicate> {
if a.is_none() {
return b;
} else if b.is_none() {
return a;
} else {
let a = Box::leak(a.unwrap());
let b = Box::leak(b.unwrap());
return Some(Box::new(move |form: &Form| a(form) && b(form)));
}
}
}

fn main() {
let pred = Foo::and(
Some(Box::new(move |form: &Form| {
form.name == String::from("bar")
})),
Some(Box::new(move |_: &Form| true)),
)
.unwrap();
let foo = Foo {
predicates: vec![pred],
};
let pred = &foo.predicates[0];
let form_a = &Form {
name: String::from("bar"),
};
let form_b = &Form {
name: String::from("baz"),
};
assert_eq!(pred(form_a), true);
assert_eq!(pred(form_b), false);
}

最佳答案

您的代码不需要 Box::leak 并且不清楚您为什么认为它需要。如果代码被删除,代码将继续编译并具有相同的输出:

impl Foo {
fn and(a: Option<Predicate>, b: Option<Predicate>) -> Option<Predicate> {
if a.is_none() {
b
} else if b.is_none() {
a
} else {
let a = a.unwrap();
let b = b.unwrap();
Some(Box::new(move |form: &Form| a(form) && b(form)))
}
}
}

unwrap 是非惯用的;更惯用的解决方案是使用 match:

impl Foo {
fn and(a: Option<Predicate>, b: Option<Predicate>) -> Option<Predicate> {
match (a, b) {
(a, None) => a,
(None, b) => b,
(Some(a), Some(b)) => Some(Box::new(move |form| a(form) && b(form))),
}
}
}

关于memory-leaks - 使用此代码是否有避免 `Box::leak` 的惯用方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56658485/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com