Function 将构造函数视为Scala中的函数-如何在映射中放置构造函数?

Function 将构造函数视为Scala中的函数-如何在映射中放置构造函数?,function,scala,constructor,Function,Scala,Constructor,我需要解析一些消息。消息的前4个字节标识消息的类型,因此,使用它,我可以实例化适当类型的对象。为了使这成为一个有效的操作,我想我应该创建一个哈希映射,其中键是前4个字节,值是对象构造函数。我可以查找构造函数并调用它 毕竟,构造函数只是函数,在映射中放置函数应该不会有任何问题。事实证明,我在这方面遇到了一些困难,因为我不知道如何正确地表达对构造函数的引用 为了通过一个简化的示例获得具体信息,假设我们有一个消息基类MsgBase,以及一对子类MsgA和MsgB。如果我为每条消息创建一个伴随对象,并在

我需要解析一些消息。消息的前4个字节标识消息的类型,因此,使用它,我可以实例化适当类型的对象。为了使这成为一个有效的操作,我想我应该创建一个哈希映射,其中键是前4个字节,值是对象构造函数。我可以查找构造函数并调用它

毕竟,构造函数只是函数,在映射中放置函数应该不会有任何问题。事实证明,我在这方面遇到了一些困难,因为我不知道如何正确地表达对构造函数的引用

为了通过一个简化的示例获得具体信息,假设我们有一个消息基类
MsgBase
,以及一对子类
MsgA
MsgB
。如果我为每条消息创建一个伴随对象,并在其中放入一个工厂函数,那么使用这些函数就可以毫无问题地生成数组

下面是一个将消息作为字符串的简化示例

class MsgBase(message: String) { }

class MsgA(message: String) extends MsgBase(message) { }

object MsgA  { def makeIt(message: String): MsgA = new MsgA(message)  }
其中
MsgB
类似。然后我可以制作地图:

val cm = Map[String, (String) => MsgBase]("a" -> MsgA.makeIt, "b" -> MsgB.makeIt)

val myMsg = cm("a")("a.This is the message")
似乎我应该能够在构建映射的表达式中直接引用消息对象构造函数,而不是在伴随对象中使用普通函数,但我还没有找到任何方法来表达这一点。有办法吗?

试试看

"a" -> (new MsgA(_))
(需要所有括号)

即使这不起作用,您当然也可以显式定义函数:

"a" -> ( (s: String) => new MsgA(s) )

对于这种情况,最好使用case类,它会自动为您提供创建新对象的函数

scala> case class MsgA(message: String) extends MsgBase(message)
scala> case class MsgB(message: String) extends MsgBase(message)
因此,您可以仅按名称引用它们,而不需要任何语法开销

scala> val m = Map("a"->MsgA, "b"->MsgB)
m: scala.collection.immutable.Map[java.lang.String,scala.runtime.AbstractFunction1[java.lang.String,Product with MsgBase]] = Map((a,<function1>), (b,<function1>))

scala> m("a")("qqq")                              
res1: Product with MsgBase = MsgA(qqq)
scala>valm=Map(“a”->MsgA,“b”->MsgB)
m:scala.collection.immutable.Map[java.lang.String,scala.runtime.AbstractFunction1[java.lang.String,带MsgBase的产品]]=Map((a,),(b,)
scala>m(“a”)(“qqq”)
res1:MsgBase=MsgA(qqq)的产品

作为一种替代方法,您可以手动使用重写的apply方法创建伴随对象。有关详细信息,请参见您的意思是
“a”->(新的MsgA()))
?非常感谢。正如我所寻找的:带占位符的短形式函数文字(Scala编程第二版第191页,以防有人想读更多)@Kim-我猜它是一个字符串,而不是一个变量,所以肯定,
“a”
。因此,您正在使用构造函数,但是,如果构造函数不带任何参数呢?有没有比
“a”->(()=>new MsgA())
更短的方法呢毕竟,构造函数就是函数,是吗?谁这么说?我的印象不同。通常,我可以对一个对象多次调用一个函数,我不必调用“new”,只要说出我脑海中出现的前两个区别就可以了。@user unknown是的,构造函数实际上是(静态)函数:(I)使用“new”是额外的语法,只是为了提醒您这是一种特殊类型的函数(许多语言省略了关键字,包括Scala的case类构造函数)。(ii)它本质上是一个静态方法;您不需要对现有对象调用构造函数(它不是方法)。
scala> val m = Map("a"->MsgA, "b"->MsgB)
m: scala.collection.immutable.Map[java.lang.String,scala.runtime.AbstractFunction1[java.lang.String,Product with MsgBase]] = Map((a,<function1>), (b,<function1>))

scala> m("a")("qqq")                              
res1: Product with MsgBase = MsgA(qqq)