我想编写类型的别名以缩短,良好和封装的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将我的类型理解为同一件事,包括与其创建者方法的伴侣对象?或者,为什么我不应该首先这样做的任何原因?

有帮助吗?

解决方案

答案实际上很简单:

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

这使我的代码可以调用ConcreteClass.Datatype,可以构建列表中所有方法的列表,而精力很少。

非常感谢Oleg的洞察力。如果您希望不委派对Concreteclass.datatype的任何呼叫,而是确切地控制您要允许呼叫者做的事情,他的答案也是最好的。

其他提示

那这个呢?

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

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top