Scala类型别名包括伴侣对象[初学者]

Jea*_*ean 7 encapsulation scala type-alias companion-object

我想编写一个类型别名来缩短,修改和封装的Scala代码.假设我有一些集合,它具有作为地图列表的属性,其值是元组.我的类型会像List[Map[Int, (String, String)]]我的应用程序允许的那样编写类似的东西或更通用的东西.我可以想象有一个超级类型要求Seq[MapLike[Int, Any]]我或其他任何漂浮我的船,具体的子类更具体.

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

class ConcreteClass {
  type DataType = List[Map[Int, (String, String)]]
  ...
}
Run Code Online (Sandbox Code Playgroud)

然后我会愉快地使用ConcreteClass#DataType我可以拿一个,并使用它.

现在假设我添加了一个函数

def foo(a : DataType) { ... }
Run Code Online (Sandbox Code Playgroud)

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

有什么方法可以让Scala把我的类型理解为同样的东西,包括带有创建者方法的伴随对象,为了缩短代码和黑盒子呢?或者,为什么我不应该首先这样做?

Jea*_*ean 7

答案其实很简单:

class ConcreteClass {
  type DataType = List[String]
}
object ConcreteClass {
  val DataType = List
}
val d = ConcreteClass.DataType.empty
Run Code Online (Sandbox Code Playgroud)

这使我的代码能够调用ConcreteClass.DataType来构建包含List中所有方法的列表,并且付出很少的努力.

非常感谢Oleg的见解.如果你不想委托给任何对ConcreteClass.DataType的调用,你的答案也是最好的,但是要精确控制你想让调用者做什么.

  • 如果你不打算将`ConcreteClass`的子类重写为`DataType`,你可能最好在同伴对象中放入`type`和`val`别名(而不是在类中有一个).这就是`scala`包对象中的别名如何工作. (2认同)

Ole*_*ako 5

那这个呢?

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