首页 > 解决方案 > 如何限制 Scala 对象中所有方法的类型?

问题描述

我正在尝试做一些我不完全确定是否可行或有意义的事情。

我有一个抽象,换句话说,它在很大程度上取决于一个对象来告诉要使用给定组件的哪个版本。它是这样的:

object ComponentManager {
  def component1Version: ComponentVersion = Component1Version1()
  def component2Version: ComponentVersion = Component2Version3()
}

我想在这里实现的是限制ComponentManagerobject 中的所有方法以符合 type ComponentVersion。我可以定义一个特征来强制执行这些类型,但我事先不知道我将拥有多少个组件。因此,我最终可能会让人们向管理器对象添加一些内容,例如:

object ComponentManager {
  def component1Version: ComponentVersion = Component1Version1()
  def component2Version: ComponentVersion = Component2Version3()
  def component3Version = objectWithWrongType()  // this is the problematic line
}

对于component3Version,我们有违规对象。它会编译,但我宁愿在发生这种情况时出现编译错误,因为我有一些检查是“自由”通过正确输入的。

同样,我不知道管理器有多少组件,所以我不能真正依赖于指定每个方法类型的特征。

我已经阅读了有关 F-bound 类型/函数/what-not 的内容,但仍然无法弄清楚它们是否/如何使它们适用于我的问题。

有任何想法吗?我认为“你的克制没有意义”也是一个可能的答案,但无论如何我都想对此有所了解。

标签: scalatypestraits

解决方案


我做出以下假设:

  • 当有人创建经理时,他们知道需要多少组件。
  • 必须声明所有组件的版本。

Traits 必须显式声明所有方法名称,因此我们不能为我们不知道的组件声明方法。相反,让我们将组件建模为一种类型:

trait ComponentManager {
  type Component
  def version(component: Component): Version
}

当有人知道他们需要什么组件时,他们可以实现一个管理器:

sealed trait MyComponent
case object Component1 extends MyComponent
case object Component2 extends MyComponent
case object Component3 extends MyComponent

object MyComponentManager extends ComponentManager {
  type Component = MyComponent
  def version(component: MyComponent): Version = component match {
    case Component1 => Component1Version1()
    case Component2 => Component2Version3()
    case Component3 => Component3Version5()
  }
}

现在:

  • 为任何组件返回除 a 之外Version的任何内容都是类型错误。
  • 忘记匹配一个组件是一个非详尽的匹配警告。

推荐阅读