[英]Rust equivalent of Java Consumer interface for Strategy pattern
我将提供一个实际的例子。
我想创建一个事件记录器。 我将事件定义为接口:
import java.util.function.Consumer;
interface Event {}
class BuyEvent implements Event {}
class SellEvent implements Event {}
记录器只是事件的消费者:
public static void main(String[] args) {
Consumer<Event> logger;
// Logger with method reference
logger = System.out::println;
logger.accept(new BuyEvent());
// Logger with lambda
logger = (event) -> {
// Do something else
System.out.println(event);
};
logger.accept(new BuyEvent());
我还可以使用 state 创建一个记录器。例如:
class StatefulLogger implements Consumer<Event> {
public StatefulLogger() {
}
@Override
public void accept(Event event) {
// Change state, then print event
System.out.println(event);
}
}
我可以按如下方式使用有状态记录器:
public static void main(String[] args) {
Consumer<Event> logger = new StatefulLogger("foo.txt");
logger.accept(new BuyEvent());
}
我正在尝试在 Rust 中实现相同的目标。
我将事件定义为枚举:
#[derive(Debug)]
enum Event {
BuyEvent,
SellEvent,
}
我定义了一个 Logger 特征和一个带有 state 的结构来实现这样的特征:
trait Logger {
fn accept(&mut self, ev: Event);
}
struct StatefulLogger {}
impl Logger for StatefulLogger {
fn accept(&mut self, ev: Event) {
// Change state, then print event
println!("{:?}", ev);
}
}
我可以按如下方式使用记录器:
fn main() {
let logger: &dyn Logger = &ComplexLogger {};
}
我希望能够为记录器分配一个闭包,与 Java 的精神大致相同。
fn main() {
let consumer: fn(Event) = |ev: Event| {
println!("{:?}", ev);
};
}
回顾一下:
在 Java 中,我使用 Consumer 接口使用 Strategy 设计模式实现了一个记录器。 记录器既可以是复杂的有状态的 object,也可以是轻量级的 lambda。
我想在 Rust 中实现相同的目标,但我不知道如何进行。 我无法在 Inte.net 上找到类似的示例。 此外,Rust 是否提供类似于 Java 的 Consumer 接口?
没有办法在 Rust 中快速解决这个问题,但您可以创建自己的宏将 lambda 转换为 Logger impl,然后返回其 object。看看这个repo 。 如果你愿意,我可以很快写一个解决方案。 以其他方式,您可以将Logger trait
更改为结构,其中为消费者定义字段。 它使您可以将任何Fn(Event)
作为消费者使用,即如果您有 state 的记录器,您可以将其移动到 lambda 并传递它或直接传递一些 fn。
#[derive(Debug)]
struct Event;
struct Logger<T>
where
T: Fn(Event),
{
consumer: T,
}
impl<T> Logger<T>
where
T: Fn(Event),
{
fn new(consumer: T) -> Self {
Self { consumer }
}
fn accept(&self, event: Event) {
(self.consumer)(event);
}
}
struct StatefulLogger;
impl StatefulLogger {
fn log(&self, event: Event) {
println!("{:?}", event);
}
}
fn log_fn(e: Event) {
println!("{:?}", e);
}
fn main() {
let foo = |e: Event| println!("{:?}", e);
let logger_lambda = Logger::new(foo);
let stateful_logger = StatefulLogger;
let logger_struct = Logger::new(move |e| stateful_logger.log(e));
let logger_fn = Logger::new(log_fn);
logger_lambda.accept(Event);
logger_struct.accept(Event);
logger_fn.accept(Event);
}
关于用户界面,请查看 Fn、FnMut 和 FnOnce 特性。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.