开发者

Scala collection of elements accessible by name

I have some Scala code roughly analogous to this:

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
}

Is there some nicer way of declaring a bunch of things and being able to access them both individually by name and collectively?

The issue I have with the code above is that the real version has almost 30 different things, and there's no way to actually ensure that each new thing I add is also added to an appropriate list (or that allThings doesn't end up with duplicates, although that's relatively easy to fix).

The various things are able to be treated in aggregate by almost all of the code base, but there are a few places and a couple of things where the individual identity matters.

I thought about just using a Map, but then the compiler looses the ability to check that the individual things being looked up actually exist (and I have to either wrap code to handle a failed lookup around every attempt, or ignore the problem and effectively risk null pointer exceptions).

I could make the kind each thing belongs to an observable property of the things, then I would at least have a single list of all things and could get lists of each 开发者_开发百科of the kinds with filter, but the core issue remains that I would ideally like to be able to declare that a thing exists, has a name (identifier), and is part of a collection.

What I effectively want is something like a compile-time Map. Is there a good way of achieving something like this in Scala?


How about this type of pattern?

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
}

You could also add a little sugar, making Things automatically convertible to List,

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

I can't think of a way to do this without the var that has equally nice syntax.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜