加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

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

发布时间:2020-12-16 18:10:58 所属栏目:安全 来源:网络整理
导读:我有一个方法,它采用Comparable并返回一个Comparable并包装另一个执行相同操作的方法: def myMethod[T : Comparable[T]](arg: T): T = otherMethod(arg)def otherMethod[T : Comparable[T]](arg: T): T = arg 这个编译,但不允许我用Int或任何其他需要隐式转
我有一个方法,它采用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)

我收到编译器错误:

inferred type arguments [T] do not conform to method otherMethod’s type parameter bounds [T <: java.lang.Comparable[T]]

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

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

这有效,但很难看.有没有更好的办法?

解决方法

以下任何一种都可以工作吗?

>在两种方法中使T的视图绑定一致,

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

>引入一个新的类型参数U<:Comparable [U]和从T到U的隐式转换,

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

您的版本的问题是T<%Comparable [T]将T转换为类型Comparable [T],但是这不满足递归类型T<:Comparable [T<:Comparable [T<:.. .]](伪代码)otherMethod期望的. 更新.要在Scala的Int中使用otherMethod或myMethod,您需要稍微帮助类型推理器,

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 =>类型的转换.可比[U].在这种情况下,只能找到一个这样的转换,它修复了U = java.lang.Integer.

顺便说一下,尝试用scalac -Xprint:typer编译这段代码.您将看到相同的隐式Predef.int2Integer用于ev1和ev2参数.

旁注:最好避免使用asInstanceOf,因为那些会破坏Scala类型系统的健全性.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读