Consider the following piece of code:
case class User(id: Int, name: String)
object User{
def unapply(str: String) = Some(User(0, str))
}
Scala complains "error: cannot resolve overloaded unapply; case class User(id: Int, str: String)" Is it not possible to overload unapply?
update: unapply with larger tuple size.
case class User(id: Int, str: String)
object User{
def unapply(s: String) = Some((User(0, s), s, 1234))
}
compiler still complains "cannot resolve overloaded unapply"
The unapply method breaks the arguments as specified and returns firstname object into an extractor . It returns a pair of strings if as an argument, the first name and last name is passed else returns none. Example : Scala.
Case Classes You can construct them without using new. case classes automatically have equality and nice toString methods based on the constructor arguments. case classes can have methods just like normal classes.
Case class constructor parameters are public val fields by default, so accessor methods are generated for each parameter. An apply method is created in the companion object of the class, so you don't need to use the new keyword to create a new instance of the class.
The one of the topmost benefit of Case Class is that Scala Compiler affix a method with the name of the class having identical number of parameters as defined in the class definition, because of that you can create objects of the Case Class even in the absence of the keyword new.
Your unapply method could not be used in pattern matching
It works with
def unapply(arg: <type to match>) : Option[(<matched fields types>)]
(no tuple if only one field, boolean instead than Option if no field).
The standard unapply of User would be (The Scala Language Specification p. 67)
def unapply(u: User) =
if (u eq null) None
else Some((u.id, u.name))
It what you want is to match a user with a zero id as in
user match {case User(name) => ....}
that would be
def unapply(u: User): Option[String] =
if(u eq null || u.id != 0) None
else Some(u.name)
If you want that a string can match as a User (this would be rather bizarre)
def unapply(s: String): Option[User] = Some(User(0, s))
It would work with
"john" match case User(u) => ... // u is User(0, john)
I guess you want the former one. In which case both your apply and the standard one are two methods with the same argument list (one User parameter), so they are not compatible. This may be seen as a little unfortunate, as when methods are called as extractors, the distinguishing element is actually the size of the result tuple, not the type of the arguments.
Your method however, while not valid as an extractor, causes no conflict. I could not find something in the spec that would forbid it. Still, it is useless and a useful method would rightly not be allowed.
The reason that you can't override the unapply (especially) is most probably that it has the same signiture as the one that is automatically created by a case class's compantion object. Remembering that a function's signiture does not take into account its return value for the piurpose of overriding.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With