Reputation: 11
I'm new to scala and I need a structure where I can easily add new indivdual accessable constants and also iterate over all of them. Something like this:
object Constants {
val A = Something(...)
val B = Something(...)
val C = Something(...)
// ...
val listOfConstants = (A, B, C, ...)
}
But without the need to add the constant to the list manually. I considered a Map but this would make it harder to access the constants and I ended up writing this:
def getElements[T : ClassTag](c : Any) : Set[T] = {
var result : Set[T] = Set()
for (field <- c.getClass.getDeclaredFields) {
field.setAccessible(true)
field.get(c) match {
case t: T => result += t
case _ =>
}
}
result
}
and then using the following line for structures like this
val listOfConstants = getElements[Something](Constants)
Is this a dirty solution? Are there better alternatives?
Upvotes: 1
Views: 1128
Reputation: 22374
You could use scala's default Enumeration
, but it has it's own caveats. The best enumaration library I know is Enumeratum. It allows you to write something like this:
object MyEnum extends Enum[Something] {
val values = findValues
case object A extends Something
case object B extends Something
case object C extends Something
case object D extends Something
}
findValues
is a macros that automatically finds all sub-objects of Something
(inside MyEnum
) in compile-time.
To add this lib using SBT:
libraryDependencies += "com.beachape" %% "enumeratum" % "1.4.0"
Upvotes: 3
Reputation: 4161
Try enumerations, for instance http://www.scala-lang.org/api/current/scala/Enumeration.html, or How to model type-safe enum types?. You can also write your enum in Java and use it from Scala
For instance, here's an enum defined in Java that you can use from Scala - and comes with a map of all its possible values, so you can get by key, iterate on the values, etc. The map of values is constructed automatically, so it does not need to be maintained manually.
import java.util.Collections;
import java.util.Map;
import java.util.HashMap;
/**
* Demonstrates parsing of an enum from the contained value
*/
public enum WithFrom implements Something {
TWO("one plus 1"), SIX("two plus 4");
WithFrom(String expr) {
this.expr = expr;
}
private final String expr;
public static final Map<String, WithFrom> fromValue = Collections
.unmodifiableMap(new HashMap<String, WithFrom>() {
private static final long serialVersionUID = 7205142682214758287L;
{
for (WithFrom wf : WithFrom.values()) {
put(wf.expr, wf);
}
}
});
}
Upvotes: 2
Reputation: 456
You could create an Enumeration and use its values: ValueSet
method.
Upvotes: 1