我需要是一个类XI可以构造一个Map,它将字符串带入其他字符串或映射,将字符串转换为字符串,然后是任意数量的其他X实例。对Scala的掌握有限,我知道我可以这样做:
class Person (stringParms : Map[String, String],
mapParms : Map[String, Map[String, String]],
children : List[X]) {
}
但是看起来不是很Scala-ish(“Scalish”?“Scalerific”?“Scalogical”?)我希望能够做到以下几点:
Person bob = Person("name" -> "Bob", "pets" -> ("cat" -> "Mittens", "dog" -> "Spot"), "status" -> "asleep",
firstChild, secondChild)
我知道我可以通过使用伴侣对象摆脱“新”,我相信我可以看看Scala varargs。我想知道的是:
递归版本真的很吸引我,因为虽然它没有解决我今天实际遇到的问题,但它整齐地映射到只包含对象和字符串(没有数字或数组)的JSON子集。
任何帮助,一如既往,非常感谢。
答案 0 :(得分:3)
->
只是制作一对(A, B)
的语法糖,所以你也可以使用它。 Map
object需要一对vararg:
def apply [A, B] (elems: (A, B)*) : Map[A, B]
如果您对模仿馆藏图书馆感兴趣,请先查看The Architecture of Scala Collections。
话虽如此,我认为您为Person
建议的签名看起来不像Map
,因为它需要变量参数,但children
与其他(String, A)
不一致"child1" -> Alice
1}}主题。如果您单独说Alice
并在内部存储def apply(elems: (String, Any)*): Person
,则可以定义:
Any
在伴侣对象中。如果PersonElem
过于宽松,您可以定义def apply(elems: (String, PersonElem)*): Person
特征
String
以及Map[String, String]
,Person
,PersonElem
等与{{1}}之间的隐式转换。
答案 1 :(得分:1)
这让你几乎到了那里。还有一张我不容易摆脱的地图。
基本方法是使用一种有点人为的参数类型,它继承自普通类型。这样,apply方法只需要一个vararg。
使用隐式转换方法我摆脱了参数类型
的丑陋构造函数case class Child
case class Person(stringParms: Map[String, String],
mapParms: Map[String, Map[String, String]],
children: List[Child]) { }
sealed abstract class PersonParameter
case class MapParameter(tupel: (String, Map[String, String])) extends PersonParameter
case class StringParameter(tupel: (String, String)) extends PersonParameter
case class ChildParameter(child: Child) extends PersonParameter
object Person {
def apply(params: PersonParameter*): Person = {
var stringParms = Map[String, String]()
var mapParms = Map[String, Map[String, String]]()
var children = List[Child]()
for (p ← params) {
p match {
case StringParameter(t) ⇒ stringParms += t
case MapParameter(t) ⇒ mapParms += t
case ChildParameter(c) ⇒ children = c :: children
}
}
new Person(stringParms, mapParms, children)
}
implicit def tupel2StringParameter(t: (String, String)) = StringParameter(t)
implicit def child2ChildParameter(c: Child) = ChildParameter(c)
implicit def map2MapParameter(t: (String, Map[String, String])) = MapParameter(t)
def main(args: Array[String]) {
val firstChild = Child()
val secondChild = Child()
val bob: Person = Person("name" -> "Bob","pets" -> Map("cat" -> "Mittens", "dog" -> "Spot"),"status"
-> "asleep",
firstChild, secondChild)
println(bob)
} }
答案 2 :(得分:0)