【问题标题】:Scala doesn't know which overload to use with primitives types wrappersScala 不知道与原始类型包装器一起使用哪个重载
【发布时间】:2014-05-14 08:27:54
【问题描述】:

我有这门课:

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
    }
}

ContentValues class 有很多 put() 方法的重载,包括:

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

在为 Float、Int、Long 和 Date 版本编译时收到以下错误:

  • 这两种方法都放在类型为 (x$1: String, x$2: Double)Unit 的类 ContentValues 中 [错误] 和方法放入类型为 (x$1: String, x$2: Float)Unit 的类 ContentValues

Scala 编译器怎么会被愚弄。

对我来说,不应该有歧义,因为可以获得完美的匹配。

这是 Scala 编译器中的错误还是设计使然?

我之前读过blog entry

使用 Scala 2.10.4。我没有用 Scala 2.11.0 测试过。

【问题讨论】:

    标签: scala primitive-types


    【解决方案1】:

    Scala 通过采用可以应用的方法然后选择其中最具体的方法来执行overload resolution

    数字扩展意味着 (java.lang.Float) 和 (java.lang.Double) 适用于 int arg,但不会提升那些装箱的 java 类型,因此两者都不是更具体的。它们是苹果和橙子。

    所以这行得通:

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

    但给定

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

    但是

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

    然而,

    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
    

    那么你就可以预先推广了:

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

    【讨论】:

    • 我认为在Java中你没有这种问题。
    • @david.perez 重载分辨率本质上是特殊的;语言对不同的边缘情况有不同的规则。
    【解决方案2】:

    一种可能的解决方案是使用:Float.box()、Long.box() 和 Int.box()。

    【讨论】:

      猜你喜欢
      • 2014-05-25
      • 1970-01-01
      • 2021-09-11
      • 2018-06-26
      • 1970-01-01
      • 1970-01-01
      • 2012-07-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多