???像 Scala 中的函数

??? like function in Scala

https://github.com/scala/scala/blob/2.11.x/src/library/scala/Predef.scala#L230

???在 scala 中是在 predef 中定义的一个函数,它抛出一个 NotImplementedError

在我的项目中,我使用 Google Guice 来注入依赖项,并且认为最好有一个类似的函数,如果注入从未发生则抛出异常,以便捕获丢失的用法注入器或缺少@Inject 注释。

在我的项目中,我有一个 class 需要注入

class OScoreboard {
  @Inject
  val source :Provider[ScoreboardBuilder] = injected;
}

和一个对象

class ExpectedInjectionException(message: String = null, cause: Throwable = null) extends RuntimeException

object injected extends Nothing{
  def apply : Nothing = {
    throw new ExpectedInjectionException("Expected an injection")
  }
}

但我收到错误消息,指出注入的类型不是 Provider[ScoreboardBuilder]

我在滥用申请吗?我还可以如何在不引用注入的对象的情况下引用 scala 函数 apply(甚至使用不同的名称)?

我还怀疑即使我修复了这个错误,该函数也会急切地 运行 在注入发生之前导致异常,这是否意味着我需要使每个注入的字段都变得惰性,或者是否有其他解决方案?

编辑:


问题是我对 Scala 的理解。

vals 是急切计算的,所以类似 ??? 的函数会立即在 class 构造上执行(由于它使用字段注入,因此会在注入发生之前立即发生)导致字段永远不会被注入。

Java 中的 final 字段等值可以 注入,因为它只是字节码验证器的限制。可以使用 reflectionGuice 可以)将 final 字段写得很好。

为了回答这个问题,需要有一种方法来延迟 ???-like function/value 的执行,直到该字段被第一次读取。我不确定如何,或者是否可能。另一种选择是将它们初始化为空。但这将导致众所周知无益的 NullPointerExceptions。我希望使用类似 null 的错误来解释注入失败。

首先:你在一个地方写了INJECTED,在另一个地方写了injected。我假设这是一个打字错误,你对两者的意思是一样的。

这样的作业:

val source :Provider[ScoreboardBuilder] = INJECTED;

将不起作用,因为您正试图将对象 INJECTED 分配给类型 Provider[ScoreboardBuilder] 的变量。该对象不是那种类型,所以你不能做那个赋值。

也许您希望该对象的行为像一个函数,并且它的 apply 方法会自动被调用,但事实并非如此。

您可以将 INJECTED 定义为 class 中的方法:

class OScoreboard {
  @Inject
  val source :Provider[ScoreboardBuilder] = INJECTED

  private def INJECTED : Nothing =
    throw new ExpectedInjectionException("Expected an injection")
}

或者你可以把它放在一个单独的对象中,但是你必须将它导入你的 class:

object injected {
  def INJECTED : Nothing =
    throw new ExpectedInjectionException("Expected an injection")
}

class OScoreboard {
  import injected._

  @Inject
  val source :Provider[ScoreboardBuilder] = INJECTED
}

问题是我对 Scala 的理解。

vals 是急切计算的,所以 ???函数在 class 构造上立即执行(因为它使用字段注入,在注入发生之前立即发生)导致抛出异常。

让它变得懒惰会导致使用反射进行注入,而不会在构造时抛出异常。然而,生成的 Java 代码并不知道发生了这种情况。因此,当第一次访问注入的值时,生成的代码会将注入的引用替换为 ???然后继续抛出异常。

我看不出有什么办法可以使这项工作成功。