Scala中存在以下预期行为或错误吗?
案例1:
class X[T1, T2]
class XExt[T1, T2] extends X[T1, T2]
class Y[T[t1] <: X[t1, _]]
class YExt extends Y[XExt]
结果 错误:XExt采用两种类型参数:预期:一个
class YExt extends Y[XExt]
^
但是以下运行正常:
class X[T1, T2]
class XExt[T1, T2] extends X[T1, T2]
class Y[T[t1, t2] <: X[t1, t2]]
class YExt extends Y[XExt]
最小化params的数量可以简化代码类型params: type T [t1]&lt;:X [t1,_] 。
案例2:
class X[T1, T2]
class Y[T[t1, t2] <: X[t1, t2]]
class Z[T <: Y[_]]
结果 错误:_ $ 1没有类型参数,预期:两个
class Z[T <: Y[_]]
^
但如果我不需要它们,如何避免定义Y参数?喜欢在:
class X[T1, T2]
class Y[T <: X[_, _]]
class Z[T <: Y[_]]
案例3:
trait A[T]
trait B[T[t] <: A[t]]
trait AExt extends A[Int]
trait BExt extends B[AExt]
结果 错误:AExt没有预期的类型参数:一个
trait BExt extends B[AExt]
^
但是为什么编译器请求一个参数(如果它已经提供)?这似乎是一个矛盾。以及如何继承B?
在IntelliJ Scala插件和Eclipse Scala IDE中观察到这种行为。所以它可能是Scala编译器的功能。
答案 0 :(得分:1)
案例1:你说Y
采用一个带有1个参数的类型,但是你给它一个有两个类型的类型。
案例2:类似,请尝试Z[T <: Y[_[_,_]]]
案例3:你说B
采用一个带有1个参数的类型,但你给它一个带有两个类型的类型。
没有错误,键盘和椅子之间存在问题。实际上该做什么?即举例,包括具体实施,然后人们可以提供更多帮助。
答案 1 :(得分:0)
误解的原因实际上是混合了抽象类型和泛型参数的概念。 错误的假设是类型参数和通用参数在约束规则中是相等的。见下文。 Z类的T1和T2是等价的。但是在ZExt中,它们可以用类XExt1和XExt2定义,它们具有不同数量的参数。 XExt2的第二个参数被忽略了。我所期望的是,使用泛型实现相同的逻辑将允许相同的语法。即Z1将接受XExt1以及XExt2(如Z中的T1和T2)。但它只接受XExt1。将XExt2作为参数放置会导致错误。
老实说还是不明白为什么不给出仿制品类型的自由。即为什么不让XExt2成为Z1的参数,允许编译器推断XExt2参数类型,只是忽略它的第二个参数。
class X[T1, T2]
class XExt1[T1] extends X[T1, Int]
class XExt2[T1, T2] extends X[T1, T2]
class Z {
type T1[t] <: X[t, _]
type T2[t] <: X[t, _]
}
class ZExt extends Z {
type T1[t] = XExt1[t]
type T2[t] = XExt2[t,_]
}
// But...
class Z1[T[t] <: X[t, _]]
class ZExt1 extends Z1[XExt1]
class ZExt2 extends Z1[XExt2] // Error: XExt2 takes two type parameters, expected: one
案件答案:
案例1:
扩展Y类的类应该完全符合T [t](有一个参数),例如:
class X[T1, T2]
class XExt[T1] extends X[T1, Int]
class Y[T[t1] <: X[t1, _]]
class YExt extends Y[XExt]
案例2:
由于@Ende Neu提到满足约束条件T [t1,t2]的额外参数,它完成了它的工作:
class X[T1, T2]
class Y[T[t1, t2] <: X[t1, t2]]
class Z[S[t1, t2] <: X[t1,t2], T <: Y[S]]
不幸的是,T [t1,t2]不能用@samthebest建议的下划线语法来描述。编译器警告“错误的顶级声明声明”:
class Z[T <: Y[_[_, _]]]
案例3:
与案例1中的问题相同.AExt应该有一个参数。例如:
trait A[T]
trait B[T[t] <: A[t]]
trait AExt[T] extends A[T]
trait BExt[T] extends B[AExt]