可通过名称访问的元素的Scala集合

时间:2011-08-01 01:43:53

标签: scala map

我有一些与此类似的Scala代码:

object Foo {
    val thingA = ...
    val thingB = ...
    val thingC = ...
    val thingD = ...
    val thingE = ...

    val thingsOfAKind = List(thingA, thingC, thingE)
    val thingsOfADifferentKind = List(thingB, thingD)
    val allThings = thingsOfAKind ::: thingsOfADifferentKind
}

是否有一些更好的方式来声明一堆东西,并且能够通过名称和集体单独访问它们?

我对上面代码的问题是真正的版本有近30种不同的东西,并且没有办法真正确保我添加的每个新东西也被添加到适当的列表中(或者allThings不会结束)重复,虽然这相对容易修复。

几乎所有的代码库都可以对各种事物进行综合处理,但是有一些地方和一些事情会影响个人身份。

我想过只使用一个Map,但是编译器失去了检查被查找的单个内容实际存在的能力(并且我必须包装代码来处理每次尝试失败的查找,或忽略问题并有效地冒空指针异常)。

我可以将每种东西都归属于事物的可观察属性,然后我至少会有一个列表中的所有东西,并且可以通过过滤器得到每种类型的列表,但核心问题仍然是我理想情况下,我希望能够声明一个东西存在,有一个名称(标识符),并且是一个集合的一部分。

我真正想要的是类似编译时的地图。在Scala中有没有一种很好的方法来实现这样的东西?

1 个答案:

答案 0 :(得分:5)

这种模式怎么样?

class Things[A] {
  var all: List[A] = Nil
  def ->: (x: A): A = { all = x :: all; x }
}

object Test {
  val things1 = new Things[String]
  val things2 = new Things[String]

  val thingA = "A" ->: things1
  val thingB = "B" ->: things2
  val thingC = "C" ->: things1
  val thingD = ("D" ->: things1) ->: things2
}

您还可以添加一点糖,使Things自动转换为List

object Things {
  implicit def thingsToList[A](things: Things[A]): List[A] = things.all
}

如果没有具有同样优秀语法的var,我无法想到这样做的方法。