gpt4 book ai didi

scala - 使用 Dynamic 调用重载方法

转载 作者:行者123 更新时间:2023-12-01 11:03:35 24 4
gpt4 key购买 nike

在 C# 中它可能使用 AsDynamic在子类上调用重载方法(示例 here ),从而允许抽象类调用它本身未定义的方法。 Scala 2.9 applyDynamic 是否可以做类似的事情?我尝试了以下

abstract class AggregateRoot extends Dynamic {
def applyChange(event: Event) {
this.applyDynamic("handleEvent")(event)
}
// this does not work
def applyDynamic(name : String)(args: Any*) = this
}

像这样使用

class InventoryItem extends AggregateRoot {
def handleEvent(event: InventoryItemCreated) {
println("received InventoryItemCreated")
}

def handleEvent(event: InventoryItemDeactivated) {
println("received InventoryItemDeactivated")
}
}

InventoryItemCreatedInventoryItemDeactivated 都是事件

class Event;

class InventoryItemDeactivated extends Event;

class InventoryItemCreated extends Event;

然后我希望能够做这样的事情

  var aggregate : AggregateRoot = new InventoryItem
var event = new InventoryItemDeactivated
aggregate.applyChange(event) // should print "received InventoryItemDeactivated"

但我不知道如何定义 applyDynamic(在 AggregateRoot 中),以便它可以在运行时调用子类中的重载方法,而无需自己定义它们。欢迎其他实现相同结果的解决方案(也许结构类型可以派上用场?)。

最佳答案

Dynamic 在这里不会给您带来任何好处,因为它的作用是让定义处理未定义方法的机制。但是,在您的示例中,所有调用的方法都已定义。

您真正想要的是查找类中定义的方法的机制,而这并不存在,因为Dynamic 意味着成为其他JVM 语言的桥梁,它们可能以完全不同的方式实现它们的“方法”。

然而,您需要做的就是使用反射。从 2.9.1 开始,Scala 没有反射库,但 Java 足以满足此目的。以下是 AggregateRoot 的编写方式:

abstract class AggregateRoot {
def applyChange(event: Event) {
this.getClass.getMethod("handleEvent", event.getClass).invoke(this, event)
}
}

Dynamic 允许您做的是:

abstract class AggregateRoot extends Dynamic {
def applyDynamic(name : String)(args: Any*) =
this
.getClass
.getMethod(name, args map (_.getClass): _*)
.invoke(this, args map (_.asInstanceOf[Object]): _*)
}

然后在最后执行此操作:

aggregate.handleEvent(event)

aggregate,因为它是 AggregateRoot 类型而不是 InventoryItem,不知道它有方法 handleEvent。但我怀疑这不是您想要的。

关于scala - 使用 Dynamic 调用重载方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8380196/

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