(使用scala 2.11.12)
这为什么要编译呢?
sealed trait Inner
sealed trait Outer {
sealed trait I extends Inner
}
case object OuterA extends Outer {
case object Inner1 extends I
case object Inner2 extends I
}
case object OuterB extends Outer {
case object Inner1 extends I
}
class Data[O <: Outer](outer: O, inner: O#I)
// I expected this not to compile but it actually does
val data = new Data(OuterA, OuterB.Inner1)为什么这不编译?
sealed trait Inner
sealed trait Outer {
type I <: Inner
}
case object OuterA extends Outer {
sealed trait OuterAInner extends Inner
override type I = OuterAInner
case object Inner1 extends OuterAInner
case object Inner2 extends OuterAInner
}
case object OuterB extends Outer {
sealed trait OuterBInner extends Inner
override type I = OuterBInner
case object Inner1 extends OuterBInner
}
class Data[O <: Outer](outer: O, inner: O#I)
// I expected this to compile but it actually does not
val data = new Data(OuterA, OuterA.Inner1)
// type mismatch;
// found : com.transparencyrights.ermine.model.V1.OuterA.Inner1.type
// required: ?#I
// Note that Inner1 extends Any, not AnyRef.
// Such types can participate in value classes, but instances
// cannot appear in singleton types or in reference comparisons.
// val data = new Data(OuterA, OuterA.Inner1)我想要实现的是一个唯一的Data构造函数,它包含两个参数,一个Outer和一个Inner,Inner类型仅限于依赖于给定Outer实例的Inner子类型。
发布于 2019-08-02 14:32:34
在这两种情况下,问题都是O#I没有按照您的要求来做。
它实际上并不是指您所拥有的特定O中的O,而是指Outer中的通用O。
可以使用路径依赖类型和通用类型约束修复这两个片段。
案例1
sealed trait Inner
sealed trait Outer {
sealed trait I extends Inner
}
final case object OuterA extends Outer {
final case object Inner1 extends I
final case object Inner2 extends I
}
final case object OuterB extends Outer {
final case object Inner1 extends I
}
final class Data[O <: Outer, I <: O#I] private (outer: O, inner: I)
object Data {
final def apply[O <: Outer, I <: O#I](outer: O, inner: I)(implicit ev: I <:< outer.I): Data[O, I] =
new Data(outer, inner)
}
val data = Data(OuterA, OuterB.Inner1) // Does not compile.
val data = Data(OuterA, OuterA.Inner1) // Does compile.案例2
sealed trait Inner
sealed trait Outer {
type I <: Inner
}
final case object OuterA extends Outer {
override final type I = OuterAInner
sealed trait OuterAInner extends Inner
final case object Inner1 extends OuterAInner
final case object Inner2 extends OuterAInner
}
final case object OuterB extends Outer {
override final type I = OuterBInner
sealed trait OuterBInner extends Inner
final case object Inner1 extends OuterBInner
}
final class Data[O <: Outer, I <: O#I] private (outer: O, inner: I)
object Data {
final def apply[O <: Outer, I <: O#I](outer: O, inner: I)(implicit ev: I <:< outer.I): Data[O, I] =
new Data(outer, inner)
}
val data = new Data(OuterA, OuterA.Inner1) // Does compile.
val data = new Data(OuterA, OuterB.Inner1) // Does not compile.现在,由于这些示例没有说明如何使用数据类和外部&内部字段,这可能还不够,但希望它对您有所帮助。
如果你有任何疑问,在征求意见时不要犹豫。
https://stackoverflow.com/questions/57326647
复制相似问题