Possible Duplicate:
Scala map containing mix type values
I have a situation where in a previous groovy program is constructing a structure like
mp = [k1: "string", k2: [d1: [1,2,3], d2: 1975], k3: 345, k4: ["one","two"]]
which amounts to:
[String: Strin开发者_JAVA百科g, String: Map[String, Any], String: Int, String: List[String]]
The function returns mp to the calling function.
as you can see the values of mp map are irregular. I am rewriting the program in scala.
In scala I have to represent mp as Map[String,Any] but this results playing the dance with isInstanceOf and asInstanceOf in the test code that makes use of mp which results in a lot of scala boilerplate code. The main reason being Scala complains about List[String] cannot be cast to Any for example.
Is there a better solution in scala?
When looking more carefully, this question is different from my previous question. In this question, as you can see the value [d1: [1,2,3], d2: "string"] for key k2 is itself is irregular map.
I was proposing this solution: Create another scala class like:
class MakeMap {
// lot of code here
....
val k1: String = // put here value found in logic above
val k2 : Map[String, Any] // here is the issue, I am again forced to use Any
val k3 : List[String] // put here value found in logic above
}
in test code:
val m1 = new MakeMap()
m1.k1 // very easy to access value, also gets rid of scala verbose syntax to access vale
// in map like getOrElse
m1.k2 // this is the issue, it seesm I have to define yet another class
m1.k3 // again easy
This message on scala-user seems to address the use case you're interested in?
If you are rewriting a code from Groovy to Scala, I suppose you are looking for performance and safety. So try to avoid using Maps to store everything because you may loose both. Try to define in advance the data structures you need, and use case class
which could be seen as immutable structs.
For instance, an equivalent of the Groovy value:
[k1: "string", k2: [d1: [1,2,3], d2: 1975], k3: 345, k4: ["one","two"]]
Could be defined as:
case class Outer( k1: String, k2: Inner, k3: Int, k4: List[String] )
case class Inner( d1: List[Int], d2: Int )
Then you can create your object mp
as:
val mp = Outer( "string", Inner( List(1,2,3), 1975 ), 345, List("one","two") )
And access members like:
val x = mp.k2.d2
Of course, give sensible names. Try first to constrain your types as much as possible, avoiding Any
, AnyRef
or AnyVal
. It's often possible to do it.
精彩评论