Reputation: 577
I think what I'm trying to do is easy, but I'm not getting the right collection of search terms. What I want is a trait that guarantees that all implementing classes have a constructor that can be invoked with an object of a known type. The syntax ought to be:
trait Message {
def this(rdr: msgpack.MsgReader): Message
}
but the compiler tells me it expects an equals sign. Any idea how to do this?
Upvotes: 0
Views: 63
Reputation: 29193
Use the typeclass pattern instead:
trait Message[T] {
def read(reader: msgpack.MsgReader): T
// Example of what would be a normal instance method.
// thiz is similar to this, except because we're in another object it must be explicitly taken as parameter.
// It's in a separate param list for convention and ease of currying
def foo(thiz: T)(param1: Int): Boolean
}
// "Implementors" don't actually implement it, the behavior exists as its own singleton
class Foo { ... }
implicit object FooMessage extends Message[Foo] {
// Note that this is not restricted to just constructors. If you want that then you are really out of luck. (And probably doing it wrong.)
override def read(reader: msgpack.MsgReader) = ???
override def foo(thiz: Foo)(param1: Int) = thiz.foo(param1)
}
// Usage
// Use an explicit, named implicit param to avoid implicitly
def readMsg[T: Message](reader: msgpack.MsgReader) = implicitly[Message[T]].read(reader)
val foo = readMsg[Foo](???)
Upvotes: 1