Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scala: method apply is defined twice when trying to overload case class apply method [duplicate]

Tags:

scala

apply

I'm trying to overload the apply method of a case class:

case class Percentage(value: Double)

object Percentage {
  def apply(value: Double): Percentage = {
    if (value < -1) new Percentage(-1.0)
    else if (value > 1) new Percentage(1.0)
    else new Percentage(value)
  }
}

but I get the following error:

method apply is defined twice conflicting symbols both originated in file

Why do I get this error?

like image 414
Simon Avatar asked Feb 05 '23 16:02

Simon


1 Answers

When you define a case class, the compiler actually generates an apply method. This is the compiled code if you skip defining the apply in the companion object:

$ javap Percentage$.class
Compiled from "SparkHangTest.scala"
public final class org.kp.funspark.Percentage$ implements scala.Serializable {
  public static final org.kp.funspark.Percentage$ MODULE$;
  public static {};
  public org.kp.funspark.Percentage apply(double);
  public scala.Option<java.lang.Object> unapply(org.kp.funspark.Percentage);
}

You're getting the error because you defined the apply with the same parameter and return types as for the generated method. So you're basically trying to override the apply method with an apply that takes the exact same arguments and has the same return type.

If you'd use another argument for apply for example, there are no conflicts:

case class Percentage(value: Double)

object Percentage {
  def apply(value: Int): Percentage = {
    if (value < -1) Percentage(-1.0)
    else if (value > 1) Percentage(1.0)
    else Percentage(value)
  }
}

And the compiled code:

$ javap Percentage$.class
Compiled from "SparkHangTest.scala"
public final class org.kp.funspark.Percentage$ implements scala.Serializable {
  public static final org.kp.funspark.Percentage$ MODULE$;
  public static {};
  public org.kp.funspark.Percentage apply(int); // This is the new apply
  public org.kp.funspark.Percentage apply(double);
  public scala.Option<java.lang.Object> unapply(org.kp.funspark.Percentage);
}
like image 171
Andrei T. Avatar answered May 01 '23 02:05

Andrei T.