7

我想写一个类型别名来缩短、漂亮和封装的 Scala 代码。假设我有一些集合,它具有映射列表的属性,其值是元组。我的类型会写一些类似的东西List[Map[Int, (String, String)]],或者我的应用程序允许的任何更通用的东西。我可以想象有一个超类型要求一个Seq[MapLike[Int, Any]]或任何漂浮在我的船上的东西,具体的子类更具体。

然后我想为这种长类型写一个别名。

class ConcreteClass {
  type DataType = List[Map[Int, (String, String)]]
  ...
}

然后,我会很高兴地ConcreteClass#DataType在任何我能拿走的地方使用它,并使用它。

现在假设我添加一个函数

def foo(a : DataType) { ... }

我想用一个空列表从外面调用它。我可以调用foo(List()),但是当我想将我的基础类型更改为另一种类型时Seq,我也必须回来更改此代码。此外,这个空列表的目的不是很明确DataType。并且伴生对象没有关联的List方法,所以不能调用DataType(), 或DataType.empty. 当我需要非空列表时会更加烦人,因为我必须写出这种长类型的重要部分。

有什么方法可以让 Scala 将我的类型理解为相同的东西,包括伴随对象及其创建者方法,以缩短代码并将其黑盒化?或者,我为什么不应该首先这样做?

4

2 回答 2

7

答案其实很简单:

class ConcreteClass {
  type DataType = List[String]
}
object ConcreteClass {
  val DataType = List
}
val d = ConcreteClass.DataType.empty

这使我的代码能够调用 ConcreteClass.DataType 以使用 List 中的所有方法构建列表,并且无需付出任何努力。

非常感谢奥列格的洞察力。如果您不想将任何对 ConcreteClass.DataType 的调用委托给 List,但他的回答也是最好的,而是精确控制您希望允许调用者执行的操作。

于 2010-10-13T04:47:43.417 回答
5

那这个呢?

class ConcreteClass {
  type DataType = List[String]
}
object DataType {
  def apply(): ConcreteClass#DataType = Nil
}
//...
val a = DataType()

于 2010-10-13T04:26:00.647 回答