rust - 如何将参数传递给存储的回调?

标签 rust

给定一个具有“处理程序”成员的“委托(delegate)”结构,我如何使用动态字符串调用处理程序?

pub struct Processor {
    callback: Box<FnMut()>,
    message: Option<String>
}

impl Processor {
    pub fn new<CB: 'static + FnMut()>(c: CB) -> Self {
        Processor {
            callback: Box::new(c),
            message: Some("".into())
        }
    }

    pub fn set_callback<CB: 'static + FnMut(&str)>(&mut self, callback: CB) {
        self.callback = Box::new(callback);
    }

    pub fn set_message<S>(&mut self, message: S) where S: Into<String> {
        self.message = Some(message.into());
    }

    pub fn process(&mut self) {
        match self.message {
            Some(string) => {
                if self.message.chars().count() > 0 {
                    (self.callback)(self.message);
                } else {
                    (self.callback)();
                }
            },
            None => {}
        }
    }
}

impl EventEmitter {
    pub fn new() -> Self {
        EventEmitter {
            delegates: Vec::new()
        }
    }

    /// Register an Event and a handler
    pub fn on(&mut self, event: Event, handler: Processor) {
        self.delegates.push(Delegate::new(event, handler))
    }

    /// Run handlers on the emitted event
    pub fn emit(&mut self, name: &'static str/*, with message!! */) {
        for delegate in self.delegates.iter_mut(){
            if delegate.event.name == name {
                delegate.handler.process();
            }
        }
    }

    /// Run handlers on the emitted event
    pub fn emit_with(&mut self, name: &'static str, message: &'static str) {
        for delegate in self.delegates.iter_mut() {
            if delegate.event.name == name {
                delegate.handler.set_message(message);
                delegate.handler.process();
            }
        }
    }
}

然后我有:

emitter.on(
    Event::new("TEST"), 
    Processor::new(|x| println!("Test: {}", x))
);
emitter.emit_with("TEST", "test");

但是编译器提示:

  --> src/main.rs:97:3
   |
97 |         Processor::new(|x| println!("Test: {}", x))
   |         ^^^^^^^^^^^^^^ --- takes 1 argument
   |         |
   |         expected closure that takes 0 arguments

如果我删除 set_callback() 定义中的“&str”类型参数:

set_callback<CB: 'static + FnMut()>(&mut self, callback: CB)

我可以使用不接受任何参数的闭包来实现它:

emitter.on( // emitter.emit("TEST");
    Event::new("TEST"), 
    Processor::new(|| println!("static string."))
);

有没有办法将字符串传递给最终可以传递给处理程序的 emit_with() 函数?

最佳答案

在这里你写了:

pub struct Processor {
    callback: Box<FnMut(/* RIGHT HERE */)>,
    message: Option<String>
}

您已经声明了一个 FnMut (闭包)不带任何参数。 语法是 FnMut(/* arguments to closure */) , 但你还没有提供任何。因此,您不能向它传递一个确实接受参数的闭包。 您不能拥有一个既接受参数又不接受参数的闭包。

此外,您使用了 FnMut(&str) ,但只在一个地方。你在任何地方都需要它。由于您想传递或不传递字符串,我已将其转换为 Optional<&str> (所以闭包类型是 FnMut(Option<&str>) )。

我修改了您的代码,使闭包采用可选的 &str。 . 这就是我建议您处理此问题的方式:

pub struct Processor {
    // The closure takes an optional string.
    callback: Box<FnMut(Option<&str>)>,
    message: Option<String>
}

impl Processor {
    pub fn new<CB: 'static + FnMut(Option<&str>)>(c: CB) -> Self {
        Processor {
            callback: Box::new(c),
            message: Some("".into())
        }
    }

    pub fn set_callback<CB: 'static + FnMut(Option<&str>)>(&mut self, callback: CB) {
        self.callback = Box::new(callback);
    }

    pub fn set_message<S>(&mut self, message: S) where S: Into<String> {
        self.message = Some(message.into());
    }

    pub fn process(&mut self) {
        match self.message {
            Some(string) => {
                // NOTE: Instead of .chars().count > 0
                if !self.message.is_empty() {
                    (self.callback)(Some(self.message));
                } else {
                    (self.callback)(None);
                }
            },
            None => {}
        }
    }
}

注意:这是未经测试的,但应该可以工作。如果出现任何错误,请发表评论。

关于rust - 如何将参数传递给存储的回调?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54548563/

相关文章:

vector - 实现二维向量语法以访问一维向量?

string - 如何从 Rust 中的另一个字符串中删除单个尾随字符串?

rust - 我如何在 Rust 中获取 SHA256 的前 4 个字节?

rust - rust collect() 如何通用地创建不同的集合

function - 如何在泛型函数中构造具体类型?

rust - 我可以将函数标记为已弃用吗?

rust - 如何为类型别名实现特征?

struct - 为 Rust 新类型自动实现封闭类型的特征(具有一个字段的元组结构)

rust - 特征向上强制强制解决方法如何工作(获取 super 特征实例的特征方法)?

visual-studio - 使用 vs 2017 的 rust 扩展为 visual studio 2017 配置 rustup