Question

I have this class:

implicit class Escritor(cv: ContentValues) extends AnyVal {
    def pon[T](col: Columna[T], valor: Int) = {
        cv.put(col.nombre, valor)
        cv
    }

    def pon[T](col: Columna[T], valor: Long) = {
        cv.put(col.nombre, valor)
        cv
    }

    def pon[T](col: Columna[T], valor: Float) = {
        cv.put(col.nombre, valor)
        cv
    }

    def pon[T](col: Columna[T], valor: Double) = {
        cv.put(col.nombre, valor)
        cv
    }

    def pon[T](col: Columna[T], valor: Date) = {
        cv.put(col.nombre, valor.getTime) // getTime returns long
        cv
    }
}

The ContentValues class has many overloads for the put() method, including:

  • put(String, Float)
  • put(String, Double)
  • put(String, Long)
  • put(String, Int)

I receive the following error when compiling for the Float, Int, Long and Date version:

  • Both method put in class ContentValues of type (x$1: String, x$2: Double)Unit [error] and method put in class ContentValues of type (x$1: String, x$2: Float)Unit

How can the Scala compiler get fooled.

For me, there shoud be no ambiguitiy, because a perfect match can be obtained.

Is this a bug in the Scala compiler or is it by design?

I've read before this blog entry.

Using Scala 2.10.4. I haven't tested with Scala 2.11.0.

Was it helpful?

Solution

Scala does overload resolution by taking the methods that could apply and then choosing the most specific among them.

Numeric widening means that (java.lang.Float) and (java.lang.Double) apply to an int arg, but those boxed java types are not promoted, so neither is deemed more specific. They are apples and oranges.

So this works:

scala> val i: java.lang.Float = 3
i: Float = 3.0

but given

scala> def f(x: java.lang.Double) = x
f: (x: Double)Double

scala> f(3.0f)
res5: Double = 3.0

but

scala> f(new java.lang.Float(3.0f))
<console>:12: error: type mismatch;
 found   : Float
 required: Double
              f(new java.lang.Float(3.0f))
                ^

Yet,

scala> object X { def f(i: java.lang.Integer) = 0 ; def f(j: java.lang.Float) = 0 ; def f(k: java.lang.Double) = 0 }
defined object X

then you can pre-promote:

scala> X f (5: java.lang.Integer)
res8: Int = 0

OTHER TIPS

One possible solution is to use: Float.box(), Long.box() and Int.box().

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top