scala - 当泛型类型与无界通配符一起使用时,不考虑类型参数绑定
问题描述
在我的项目中,我有一个这样的星座:
trait F
trait X[A <: F]
def test(x: X[_]): X[_ <: F] = x
TraitX
有一个类型参数,其上限为F
. 据我了解,类型X[_]
应该X[_ <: F]
是等价的。但是scalac
2.12.5 抱怨一个不能分配给另一个。
$ scalac -Xscript test test.scala
test.scala:5: error: type mismatch;
found : this.X[_$1] where type _$1
required: this.X[_ <: this.F]
def test(x: X[_]): X[_ <: F] = x
^
我想不出这个任务会使一个健全的程序变得不健全的情况。这个任务被拒绝的原因是什么?有没有办法允许这样的分配(也许在一个更复杂的例子中)是有问题的?
解决方案
这个赋值并没有真正的问题,编译器甚至知道这一点,因为下面的实现编译没有问题:
trait F
trait X[A <: F]
def test(x: X[_]): X[_ <: F] = x match { case q: X[t] => q }
如果您允许类型检查器为类型变量推断更精确的界限,从而给类型检查器一些松懈t
,它最终会确定t
必须是 的子类型F
,然后允许您返回值q
(与 相同x
)而不会抱怨。由于某些可能与 Java 通配符互操作性有关的违反直觉的原因,默认情况下它不会这样做。
(再次取消删除;我最初的猜测似乎并不太遥远,鉴于 Dmytro Mitin 的链接,相比之下,它甚至看起来都没有那么模糊。)
推荐阅读
- cookies - 限制网站上所有 cookie 的最大使用期限或过期时间
- javascript - 如何取消选择 oracle apex 中的导航子菜单?
- asp.net - 有没有办法在使用 jExcel 或 jSpreadsheet 创建的报告中检查和显示数据库中的实时更新数据?
- node.js - Firebase 上的网站没有得到我的服务器 nodejs express 的 cookie(oauth2 不和谐护照)
- laravel - 错误的响应代码 URL 返回了错误的 HTTP 响应代码
- javascript - 将捕获按钮添加到捕获窗口的底部中心
- c++ - 重载箭头运算符为 ref 合格
- excel - 数据帮助和提示
- c# - 为什么使用 64 位哈希而不是字符串时字典的内存消耗会增加?
- reactjs - React中如何将子元素传递给父元素