scala - Scala - 使用泛型类型参数的内部类型定义无法编译
问题描述
我正在尝试定义算术表达式树表示。DataElement 表示单个键值对。CalcElement 表示一对子(计算或数据)元素。对于 CalcElement,键是子元素中键的元组。CalcElement 的值是使用其 apply 方法的子元素值的组合。
以下代码无法编译,我正在努力弄清楚为什么它不应该编译。
trait DataElement[K] {
type KeyType = K
def key:KeyType
def value:Double
}
trait CalcElement[OP1<:DataElement[_], OP2<:DataElement[_]] extends DataElement[(OP1#KeyType, OP2#KeyType)] //FIRST ERROR
{
def op1: OP1
def op2: OP2
def apply: (OP1, OP2) => Double
def unapplyFirst: (Double, OP1) => OP2
def unapplySecond: (Double, OP2) => OP1
def key: (OP1#KeyType, OP2#KeyType) = (op1.key, op2.key) // SECOND AND THIRD ERROR
def value: Double = apply(op1, op2)
}
第一个错误是
Error:(12, 84) illegal inheritance;
self-type CalcElement[OP1,OP2] does not conform to DataElement[(_$1, _$2)]'s selftype DataElement[(_$1, _$2)]
trait CalcElement[OP1<:DataElement[_], OP2<:DataElement[_]] extends DataElement[(OP1#KeyType, OP2#KeyType)]
第二个和第三个错误是
Error:(21, 46) type mismatch;
found : (some other)_$1(in type OP1)
required: _$1(in type OP1)
def key: (OP1#KeyType, OP2#KeyType) = (op1.key, op2.key)
Error:(21, 55) type mismatch;
found : (some other)_$2(in type OP2)
required: _$2(in type OP2)
def key: (OP1#KeyType, OP2#KeyType) = (op1.key, op2.key)
可以在这里帮助理解编译器的思维方式。
干杯
解决方案
在您的示例中, KeyType 在构造类型之前是未定义的。因此,OP1#KeyType 和 OP2#KeyType 将不起作用。
要么这样做:
trait CalcElement[OP1<:DataElement[Double], OP2<:DataElement[Double]]
extends DataElement[(OP1#KeyType, OP2#KeyType)]
或这个:
trait CalcElement[X, Y, OP1<:DataElement[X], OP2<:DataElement[Y]]
extends DataElement[(OP1#KeyType, OP2#KeyType)]
我无法理解的是,为什么需要传递 KeyType 来构造 DataElement?因为,计算可以是一棵树,所以为什么不能这样:
trait CalcElement[OP1<:DataElement[_], OP2<:DataElement[_]]
extends DataElement[(OP1, OP2)]
?
推荐阅读
- linkedin - 无法使用 LinkedIn API v. 2 在 LinkedIn 上共享
- asp.net-core-mvc - 使用 Azure AD 身份验证 (B2C) 显示 Core MVC 的头像
- hibernate - 级联 - 更改也从非拥有方传播?
- sqlalchemy - 如何使用 pyhive sqlalchemy 连接到 Databricks 集群?
- linq - 读取 XML 枚举没有产生任何结果
- python - 从文件加载时打印作为字典存储在列表中的值
- arrays - 如何搜索字符串数组并快速返回特定值?
- c++ - 从 wxTextCtrl 中获取数值
- mongodb - 无法使用带有服务器 CA 验证的 TLS 连接到 AWS 数据库
- javascript - Vue 组件方法中的错误-with-debounce 永远不会被报告