我有一种情况,在之前的groovy程序中构建一个像
这样的结构mp = [k1: "string", k2: [d1: [1,2,3], d2: 1975], k3: 345, k4: ["one","two"]]
相当于:
[String: String, String: Map[String, Any], String: Int, String: List[String]]
该函数将mp返回给调用函数。
你可以看到mp map的值是不规则的。我正在用scala重写程序。
在scala中我必须将mp表示为Map [String,Any],但是这会导致在使用mp的测试代码中使用isInstanceOf和asInstanceOf进行舞蹈,这导致了大量的scala样板代码。 Scala抱怨List [String]的主要原因不能转换为Any。例如。
scala有更好的解决方案吗?
仔细观察时,这个问题与我之前的问题有所不同。在这个问题中,你可以看到关键k2的值[d1:[1,2,3],d2:“string”]本身就是不规则的地图。
我提出了这个解决方案: 创建另一个scala类,如:
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
}
在测试代码中:
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
答案 0 :(得分:2)
This消息似乎解决了您感兴趣的用例?
答案 1 :(得分:1)
如果您正在将代码从Groovy重写为Scala,我想您正在寻找性能和安全性。因此,尽量避免使用地图来存储所有内容,因为您可能会松开两者。尝试事先定义所需的数据结构,并使用可以看作不可变结构的case class
。
例如,等效于Groovy值:
[k1: "string", k2: [d1: [1,2,3], d2: 1975], k3: 345, k4: ["one","two"]]
可以定义为:
case class Outer( k1: String, k2: Inner, k3: Int, k4: List[String] )
case class Inner( d1: List[Int], d2: Int )
然后您可以将对象mp
创建为:
val mp = Outer( "string", Inner( List(1,2,3), 1975 ), 345, List("one","two") )
并访问以下成员:
val x = mp.k2.d2
当然,给出明智的名字。首先尝试尽可能限制您的类型,避免Any
,AnyRef
或AnyVal
。通常可以这样做。