如何拥有一个接受来自另一个变量的闭包调用方法的结构?
How to have a struct that accepts closures calling methods from another variable?
所以我今年在做代码的出现,遇到了一个借用问题:
如何让结构接受闭包从另一个变量调用方法?这是我想出的一个最小示例。借用检查器不喜欢这两个闭包都借用值。
如果我有一个围绕值的互斥锁,那么它似乎可以工作,但我希望有一个更优雅的解决方案。
本质上,我希望不同的 Brains 具有不同的 input/output 功能,其中一个可能只打印输出,另一个可能将输出添加到 vec。
struct Brain<I, O>
where
I: Fn() -> i32,
O: FnMut(i32),
{
input: I,
output: O,
}
impl<I, O> Brain<I, O>
where
I: Fn() -> i32,
O: FnMut(i32),
{
fn new(input: I, output: O) -> Self {
Brain { input, output }
}
}
fn runner() {
let mut values = Vec::new();
let request_input = || *values.last().unwrap();
let add_output = |v| values.push(v);
let _ = Brain::new(request_input, add_output);
}
你做错了,你显然不能在 rust 中这样做,你只能有一个可变引用或一个和多个引用,但不能同时有两个。与其使用像 Mutex
或 Cell
这样的内部可变性,我建议你使用一个特征,例如你可以这样做:
trait Bus {
fn input(&self) -> i32;
fn output(&mut self, v: i32);
}
struct Brain<T>
where
T: Bus,
{
bus: T,
}
impl<T> Brain<T>
where
T: Bus,
{
fn new(bus: T) -> Self {
Brain { bus }
}
}
struct MyBus {
values: Vec<i32>,
}
impl Bus for MyBus {
fn input(&self) -> i32 {
*self.values.last().unwrap()
}
fn output(&mut self, v: i32) {
self.values.push(v)
}
}
fn main() {
let bus = MyBus { values: Vec::new() };
let _ = Brain::new(bus);
}
这允许很大的灵活性。
所以我今年在做代码的出现,遇到了一个借用问题:
如何让结构接受闭包从另一个变量调用方法?这是我想出的一个最小示例。借用检查器不喜欢这两个闭包都借用值。
如果我有一个围绕值的互斥锁,那么它似乎可以工作,但我希望有一个更优雅的解决方案。
本质上,我希望不同的 Brains 具有不同的 input/output 功能,其中一个可能只打印输出,另一个可能将输出添加到 vec。
struct Brain<I, O>
where
I: Fn() -> i32,
O: FnMut(i32),
{
input: I,
output: O,
}
impl<I, O> Brain<I, O>
where
I: Fn() -> i32,
O: FnMut(i32),
{
fn new(input: I, output: O) -> Self {
Brain { input, output }
}
}
fn runner() {
let mut values = Vec::new();
let request_input = || *values.last().unwrap();
let add_output = |v| values.push(v);
let _ = Brain::new(request_input, add_output);
}
你做错了,你显然不能在 rust 中这样做,你只能有一个可变引用或一个和多个引用,但不能同时有两个。与其使用像 Mutex
或 Cell
这样的内部可变性,我建议你使用一个特征,例如你可以这样做:
trait Bus {
fn input(&self) -> i32;
fn output(&mut self, v: i32);
}
struct Brain<T>
where
T: Bus,
{
bus: T,
}
impl<T> Brain<T>
where
T: Bus,
{
fn new(bus: T) -> Self {
Brain { bus }
}
}
struct MyBus {
values: Vec<i32>,
}
impl Bus for MyBus {
fn input(&self) -> i32 {
*self.values.last().unwrap()
}
fn output(&mut self, v: i32) {
self.values.push(v)
}
}
fn main() {
let bus = MyBus { values: Vec::new() };
let _ = Brain::new(bus);
}
这允许很大的灵活性。