斯卡拉类型别名包括伴侣对象[初学]
我想写一个类型别名缩短,漂亮和封装的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()
This works。谢谢。然而,为此我必须定义List的每一种方法来做我想做的事情,并且它有点冗长。控制可以调用的内容也是非常好的。感谢你的回答,我想我得到了“可以调用所有列表方法”的通用解决方案:现在发布它。非常感谢:) – Jean 2010-10-13 04:44:46
如果你不打算'ConcreteClass'的子类来重载'DataType',你最好把'type'和'val'别名放在伴随对象中(而不是在类中有一个) )。这是'scala'包对象中的别名的工作原理。 – 2010-10-13 12:22:23
你确实很对。我从现在开始做。谢谢。 – Jean 2010-10-13 12:51:38
除了d是类型List [Nothing] – sourcedelica 2012-07-08 03:01:17