【问题标题】:Scala: How do I check that a dynamically loaded class implements a trait?Scala:如何检查动态加载的类是否实现了特征?
【发布时间】:2018-11-13 00:34:45
【问题描述】:

我正在尝试构建一个 Scala 应用程序,用户可以在其中加载实现由 trait 定义的接口的类,然后应用程序将使用该接口。

例如,我的 Operator trait

trait Operator {
    def operate(a: Int, b: Int): Int
}

由要在运行时加载的用户定义类实现,添加。

class Add {
  def operate(a: Int, b: Int): Int = a + b
}

应用程序如何检查这个 Add 类是否实现了它所知道的 Operator trait?我希望能够在已加载类的实例上调用 operate

我尝试过像这样的简单模式匹配

case op: Class[Operator] => op.newInstance()

但这似乎是根据特征名称而不是成员签名来检查实现。

【问题讨论】:

  • 会员签名 ?你的 Add 类没有实现 Operator 特征。
  • “成员签名”可能是错误的术语。我的意思是模式匹配不是检查Add 是否使用适当的参数和输出类型实现了一个名为operate 的函数。我看到Add 没有实现Operator,但包括它似乎没有帮助。重要的是,我正在寻找一种可以独立编译应用程序和 Add 类的方法,以便用户编写一个遵循 Operator trait 准则但不能直接访问应用程序源代码的类。
  • Add实现Operator,而不是想出一些鸭式打字方案不是更容易吗?

标签: scala pattern-matching traits


【解决方案1】:

首先,让我们澄清一下术语,您的 class Add 根本没有 implement 您定义的 Operator 特征。您不应该也不能使用定义明确的术语来表达与实际含义不同的意思。

现在,您要查找的是 structural types 而不是 traits

让我们定义一个名为IsOperatorstrucural type

type IsOperator = {
  def operate(a: Int, b: Int): Int
}

让我们定义一些使用它的逻辑,

def perform(a: Int, b: Int, o: IsOperator): Int = o.operate(a, b)

现在,任何object 或任何与structural type IsOperate 确认的class 的实例(有一个名为operate 类型(Int, Int) => Int 的方法)都可以与perform 一起使用。

object Add {
  def operate(a: Int, b: Int): Int = a + b
}

val sum = perform(1, 2, Add)
// sum: Int = 3

【讨论】:

  • 谢谢!这正是我想要的。
  • 一个重要的补充是,虽然 Scala 支持这一点,但这并不意味着这是一个好主意。
  • main 也只是一个方法签名。这也不是一个好主意...
  • 危急时刻需要采取危急措施。
  • 那么现在如何“检查动态加载的类是否实现了[结构类型]”?我猜是用try ... catch { case e: NoSuchMethodException => ... }包围o.operate(a, b)
猜你喜欢
  • 2012-03-25
  • 1970-01-01
  • 2020-06-04
  • 2013-07-03
  • 2014-09-26
  • 2021-09-27
  • 2010-09-21
  • 2021-09-30
  • 1970-01-01
相关资源
最近更新 更多