如何在另一个构造函数中获取类似 Map 的糖
我需要是一个类XI,它可以用一个将字符串放入其他字符串的映射或将字符串放入字符串的映射,然后构造任意数量的其他X实例。由于我对Scala,我知道我可以做到这一点:
class Person (stringParms : Map[String, String],
mapParms : Map[String, Map[String, String]],
children : List[X]) {
}
但这看起来不太像 Scala(“Scalish”?“Scalerific”?“Scaological”?)我希望能够做到以下几点:
Person bob = Person("name" -> "Bob", "pets" -> ("cat" -> "Mittens", "dog" -> "Spot"), "status" -> "asleep",
firstChild, secondChild)
我知道我可以通过使用伴生对象摆脱“新”,我确信我可以查看 Scala 可变参数。我想知道的是:
- 我如何使用 -> (或一些类似合理的运算符)来构造要在构造中制作成 Map 的元素?
- 我如何定义一个映射,以便它可以在两种完全不同的类型之间进行类似选项的切换,或者成为递归树,其中每个(命名)节点指向字符串形式的叶子或像它自己一样的另一个节点?
递归版本确实很吸引我,因为虽然它没有解决我今天实际遇到的问题,但它巧妙地映射到仅包含对象和字符串(没有数字或数组)的 JSON 子集。
一如既往,非常感谢任何帮助。
What I need is a class X I can construct with a Map that takes Strings into either other Strings or Maps that take Strings into Strings, and then an arbitrary number of other instances of X. With my limited grasp of Scala, I know I can do this:
class Person (stringParms : Map[String, String],
mapParms : Map[String, Map[String, String]],
children : List[X]) {
}
but that doesn't look very Scala-ish ("Scalish"? "Scalerific"? "Scalogical"?) I'd like to be able to do is the following:
Person bob = Person("name" -> "Bob", "pets" -> ("cat" -> "Mittens", "dog" -> "Spot"), "status" -> "asleep",
firstChild, secondChild)
I know I can get rid of the "new" by using the companion object and I'm sure I can look Scala varargs. What I'd like to know is:
- How I can use -> (or some similarly plausible operator) to construct elements to be made into a Map in the construction?
- How I can define a single map so either it can do an Option-like switch between two very disparate types or becomes a recursive tree, where each (named) node points to either a leaf in the form of a String or another node like itself?
The recursive version really appeals to me because, although it doesn't address a problem I actually have today, it maps neatly into a subset of JSON containing only objects and strings (no numbers or arrays).
Any help, as always, greatly appreciated.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
->
只是一个语法糖来组成一对(A, B)
,因此您也可以使用它。Map
对象接受成对的 vararg:您应该首先查看 架构Scala Collections(如果您有兴趣模仿集合库)。
话虽如此,我不认为您为
Person
提出的签名看起来像Map
,因为它需要变量参数,但children
却不是与其他(String, A)
主题连续。如果你说“child1”-> Alice
,并在内部单独存储Alice
,您可以在伴随对象中定义:。如果
Any
太宽松,您可以定义PersonElem
特征,以及
String
、Map[String, String]
之间的隐式转换code>、Person
等到PersonElem
。->
is just a syntactic sugar to make a pair(A, B)
, so you can use it too.Map
object takes a vararg of pairs:You should first check out The Architecture of Scala Collections if you're interested in mimicking the collections library.
Having said that, I don't think the signature you proposed for
Person
looks likeMap
, because it expects variable argument, yetchildren
are not continuous with the other(String, A)
theme. If you say"child1" -> Alice
, and internally storeAlice
seperately, you could define:in the companion object. If
Any
is too loose, you could definePersonElem
trait,and implicit conversion between
String
,Map[String, String]
,Person
, etc toPersonElem
.这让你几乎成功了。还有一张地图我无法轻易摆脱。
基本方法是拥有一个有点人为的参数类型,它继承自通用类型。这样,apply 方法只需要一个 vararg。
使用隐式转换方法,我摆脱了参数类型的丑陋构造函数
This gets you almost there. There is still a Map I don't get easily rid of.
The basic approach is to have a somewhat artificial parameter types, which inherit from a common type. This way the apply method just takes a single vararg.
Using implicit conversion method I get rid of the ugly constructors for the parameter types
这是一种方法:
用法:
Here's one way:
Usage: