I started studying recently Scala. And I don't understand why this code is not working. Can anybody help me?
import scala.collection.mutable
import scala.collection.mutable.Map
class Bijection[T] (val v: Set[T]) {
private var addition = 0
private var reversed = false
def add(i: Int)(implicit ev: T <:< Int) = {
addition += i
}
def reverse(implicit ev: T <:< String) = {
reversed = !reversed
}
}
object Bijection {
def apply(s: Set[String]): Bijection[String] = {
println("Hello string")
Bijection(s)
}
def apply[T](s: Set[T]): Bijection[T] = {
println("Hello T")
Bijection(s)
}
}
object Main {
def main(args: Array[String]): Unit = {
var x = Bijection[String](Set[String]("fd", "fasf"))
}
}
This code should print "Hello" But I get now next trace.
Error:(23, 7) double definition:
def apply(s: Set[String]): Bijection[String] at line 18 and
def apply[T](s: Set[T]): Bijection[T] at line 23
have same type after erasure: (s: scala.collection.immutable.Set)Bijection
def apply[T](s: Set[T]): Bijection[T] = {
The JVM doesn't have reified generics , instead, it erases type parameters at runtime, even though they're stored in bytecode. The only reason it has type parameters are to check things at compile time. Because of this, your 2 apply methods will both have the signature.
def apply(s: Set): Bijection
at runtime.
Because of this, there's no way for the right apply method to be chosen.
Furthermore, you have to call the constructor inside the apply method. If you don't use new
, then you'll just call the same apply method again, going into infinite recursion.
Instead, you can do something like this. If it's not a string, the implicit parameter will remain null, and you will know that it is not a String
but some other T
.
object Bijection {
private def applyString(s: Set[String]): Bijection[String] = {
println("Hello String")
new Bijection(s)
}
private def applyT[T](s: Set[T]): Bijection[T] = {
println("Hello T")
new Bijection(s)
}
def apply[T](s: Set[T])(implicit ev: Set[T] =:= Set[String] = null): Bijection[T] =
if (ev == null) applyT(s) else applyString(s).asInstanceOf[Bijection[T]]
}
You don't have to change anything else.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.