I need to parse some messages. The first 4 bytes of a message identify the type of message, so, using that, I can instantiate an object of the proper type. To make this an efficient operation, I thought I would create a hash map where they key is the first 4 bytes, and the value is the object constructor. I can just look up the constructor and invoke it.
After all, constructors are just functions, and there shouldn’t be any problem putting functions in a map. It turns out that I am having some difficulty with this because I don’t know how to express the reference to the constructor properly.
To get concrete with a simplified example, suppose we have a message base class, MsgBase, and a couple subclasses, MsgA and MsgB. If I create a companion object for each of the messages and put a factory function into it, I can make the array without any problem using those functions.
Here is a simplified sample which takes the message as a string.
class MsgBase(message: String) { }
class MsgA(message: String) extends MsgBase(message) { }
object MsgA { def makeIt(message: String): MsgA = new MsgA(message) }
and where MsgB is similar. Then I can make the map:
val cm = Map[String, (String) => MsgBase]("a" -> MsgA.makeIt, "b" -> MsgB.makeIt)
val myMsg = cm("a")("a.This is the message")
It seems like I should be able to refer to the message object constructor directly in the expression building the map, rather than using the trivial function in the companion object, but I haven’t figured out any way to express that. Is there a way?
Try
(all parentheses are needed).
Even if this didn’t work, you could of course always define the function explicitly: