泛型 – Scala参数化类型问题,返回相同类型的实例
在下文中,我将仅提供我的
Scala代码的非常简化版本.足以显示问题.不必要的代码块将减少为……
有效的部分 我创建了一个矢量库(即用于建模数学向量,而不是scala.collection.Vector意义上的向量).基本特征如下: trait Vec[C] extends Product { def -(o:Vec[C]):Vec[C] = ... ... } 我为特定的载体创建了许多亚型,例如用于二维向量的Vec2,或用于二维Int向量的Vec2Int. 子类型缩小了某些操作的返回类型.例如,从另一个向量中减去Vec2Int将不会返回通用的Vec [Int],而是返回更具体的Vec2Int. 另外,我已经在Vec2Int等非常特定的子类型中声明了这些方法,因此允许编译器选择这些内联方法. 这非常有效,我已经为矢量计算创建了一个快速且可用的库. 在此基础上,我现在想要创建一组类型来模拟基本的几何形状.基本的形状特征如下: trait Shape[C,V <: Vec[C]] extends (V=>Boolean) { def boundingBox:Box[C,V] } 其中Box将是Shape的子类型,对n维框进行建模. 不起作用的部分 现在,我试图定义框: trait Box[C,V <: Vec[C]] extends Shape[C,V] { def lowCorner:V def highCorner:V def boundingBox = this def diagonal:V = highCorner - lowCorner // does not compile } 对角线方法不能编译,因为方法Vec.-返回Vec [C],而不是V. 当然,我可以使对角线返回Vec [C],但这在很多方面都是不可接受的.这一次,我将失去特定Vec子类型的编译器优化.此外,例如,当你有一个由两个二维浮动向量(Vec2Float)描述的框时,假设对角线也是Vec2Float是很有意义的.我不想丢失这些信息. 我试图解决这个问题 按照Scala集合层次结构的示例,我介绍了一个类型VecLike: trait VecLike[C,+This <: VecLike[C,This] with Vec[C]] { def -(o:Vec[C]):This ... } 我让Vec扩展了它: trait Vec[C] extends Product with VecLike[C,Vec[C]] ... (然后我会继续创建更具体的VecLike子类型,如Vec2Like或Vec3Like,以配合我的Vec类型层次结构.) 现在,Shape和Box的新定义如下所示: trait Shape[C,V <: VecLike[C,V] with Vec[C]] ... trait Box[C,V] with Vec[C]] extends Shape[C,V] { ... def diagonal:V = highCorner - lowCorner } 仍然,编译器抱怨: Error: type mismatch; found: Vec[C] required: V 这让我很困惑.类型VecLike在minus方法中明确返回This,它转换为Box类型的类型参数V.我可以看到Vec的减法仍然返回Vec [C],但是为什么编译器此时不能使用返回类型的VecLike的减法? 我该如何解决这个问题? 解决方法
我的建议是在省略你认为无关的代码时更加努力,只显示代码.人们经常设法删除重要的部分真是太神奇了.口头禅是“如果你不知道为什么它不起作用,那么你就不知道什么是相关的.”这是非常认真的,真实的建议:如果你给我编译的代码除了你不理解的东西外,我可以在五秒钟内给你帮助,或者如果我必须重建你所有的碎片,我可以在五分钟内帮助你遗漏了猜猜哪一个经常发生.
关于代码.在我猜测第一次尝试的位如何填充到第二次尝试之后,它完全按照给定的方式编译. (这个“猜测”阶段是预先显示代码的另一个好理由.) trait VecLike[C,This] with Vec[C]] { def -(o: Vec[C]): This } trait Vec[C] extends Product with VecLike[C,Vec[C]] { } trait Shape[C,V] with Vec[C]] { } trait Box[C,V] { def lowCorner: V def highCorner: V def boundingBox = this def diagonal: V = highCorner - lowCorner } % scalac281 a.scala % (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- bootstrap 使用table表单布局 隐藏显示行
- scala – 有什么方法可以部署静态文件,以便Spray可以为它们
- angularjs – 角度ng重复添加引导行每3或4 cols
- yum仓库基础操作
- scala – 使用IntelliJ Idea 14上的Activator问题进行游戏
- [webservice] 基于Axis2的WebService开发及Demo下载(包含ja
- 吴裕雄 Bootstrap 前端框架开发——Bootstrap 表格:边框表
- sed命令详解--转
- QuickServer--在吵闹的环境里快速搭建自己的TcpServer(Prag
- angularjs – ngRepeat更新后的指令
- [Bash] Move and Copy Files and Folders with B
- scala – 在Akka集群中同步数据的简单方法?
- state-management – 如何在NGXS中使用patchStat
- 如何使用bash脚本递归删除文件中的特定扩展名
- angularjs / rendering内联或使用ng-include之间
- 角度模拟 – 只是模拟显式请求.通过所有意外的请
- twitter-bootstrap – Bootstrap 3仅用于移动
- 配置 – 将OpenLDAP从cn = config切换到slapd.co
- angularjs – 重复Angular中的转换 – 访问当前项
- 如何在bash中使用cut命令显示除指定的所有列之外