视图绑定与上层类型绑定不兼容?

时间:2011-08-27 22:47:28

标签: scala

我有一个方法,它接受一个Comparable并返回一个Comparable并包装另一个执行相同操作的方法:

def myMethod[T <: Comparable[T]](arg: T): T = otherMethod(arg)
def otherMethod[T <: Comparable[T]](arg: T): T = arg

这是编译,但不允许我用Int或任何其他需要隐式转换来实现Comparable的类型调用myMethod。据我了解,视图边界旨在解决此类问题,但使用视图绑定

def myMethod[T <% Comparable[T]](arg: T): T = otherMethod(arg)

我收到编译错误:

  

推断类型参数[T]不符合方法otherMethod的类型参数bounds [T&lt;:java.lang.Comparable [T]]

到目前为止,我提出的唯一解决方法是使用第二个类型参数并在两者之间进行投射:

def myMethod[T <% Comparable[T], U <: Comparable[U]](arg: T): T =
  otherMethod(arg.asInstanceOf[U]).asInstanceOf[T]

这很有效,但很难看。还有更好的方法吗?

1 个答案:

答案 0 :(得分:6)

以下任何一项都有效吗?

  1. 使T的视图在两种方法中都保持一致,

    def otherMethod[T <% Comparable[T]](arg: T): T = arg
    def myMethod[T <% Comparable[T]](arg: T): T = otherMethod(arg)
    
  2. 引入新的类型参数U <: Comparable[U]以及从TU的隐式转换,

    def otherMethod[T <: Comparable[T]](arg: T): T = arg
    def myMethod[U <: Comparable[U], T <% U](arg: T): U = otherMethod(arg)
    
  3. 您的版本存在的问题是T <% Comparable[T]T转换为Comparable[T]类型,但这不符合递归类型T <: Comparable[T <: Comparable[T <: ...]]伪代码otherMethod期望。


    更新。要在Scala otherMethod中使用myMethodInt,您需要稍微帮助类型推理器,

    myMethod(2)                    // Int value types don't implement Comparable
    myMethod(2: java.lang.Integer) // Apply implicit conversion (Int => java.lang.Integer)
    

    更新2 。在评论中,您说您愿意让myMethod更加丑陋,以改善呼叫站点的类型推断。这是一种方式,

    def myMethod[U <: Comparable[U], T](arg: T)
         (implicit ev1: T => U, ev2: T => Comparable[U]): U = otherMethod(arg)
    myMethod(2) // returns java.lang.Integer(2)
    

    诀窍是使用两个隐式转换:实际应用ev1,而ev2仅用于辅助类型推断。后者要求Scala搜索其含义为Int => Comparable[U]类型的转换。在这种情况下,只能找到一个这样的转换,它修复了U = java.lang.Integer

    顺便说一句,尝试使用scalac -Xprint:typer编译此代码。您会看到同一隐式Predef.int2Integer用于ev1ev2参数。

    旁注:最好避免asInstanceOf强制转换,因为这些会破坏Scala类型系统的健全性。