使用带类型选择的 Aux 模式时发生反射调用
Reflective call occurred when using Aux pattern with type selection
考虑以下示例:
sealed trait Granularity
object Granularity {
case object Full extends Granularity
sealed trait Partial extends Granularity {
type GranularityKey
}
case object StringGranularity extends Partial {
override type GranularityKey = String
}
}
sealed trait Test{
type T <: Granularity
}
object Test {
type Aux[TT <: Granularity] = Test{ type T = TT }
case object Cmp extends Test{
override type T = StringGranularity.type
}
case object Fll extends Test{
override type T = Full.type
}
}
case class Tst[Gran <: Partial, T <: Test.Aux[Gran]](t: T#T#GranularityKey)
^
|___Advanced language feature: reflective call
在类型选择中出现了一些反射调用的想法信号T#T#GranularityKey
。
您能解释一下这里会发生什么反射调用吗?那么它实际上是类型安全的吗?
也许,因为下一个 type Aux[TT <: Granularity] = Test{ type T = TT }
- 基本上你在这里说有一些 Test
应该在其中定义类型别名 T
。我认为此处的编译器逻辑类似于 Scala 实现中的 Duck Typing。例如,您可以定义 type Foo{ def bar(): Unit}
并尝试下一个
class FooImpl {
def bar(): Unit = println("Bar")
}
val foo: Foo = new FooImpl
foo.bar()
如你所见FooImpl
没有继承任何东西,但仍然可以分配给类型Foo
,因为它满足具有方法bar
的条件,但由于JVM限制或字节- 代码限制 - foo.bar()
调用将是反射式的,意思是 Java 反射 API。但是,尽管如此,这种方法是完全类型安全的。
也许,Idea 因此也认为 Test
特征中的类型别名 T
将通过反射 API.
被调用
考虑以下示例:
sealed trait Granularity
object Granularity {
case object Full extends Granularity
sealed trait Partial extends Granularity {
type GranularityKey
}
case object StringGranularity extends Partial {
override type GranularityKey = String
}
}
sealed trait Test{
type T <: Granularity
}
object Test {
type Aux[TT <: Granularity] = Test{ type T = TT }
case object Cmp extends Test{
override type T = StringGranularity.type
}
case object Fll extends Test{
override type T = Full.type
}
}
case class Tst[Gran <: Partial, T <: Test.Aux[Gran]](t: T#T#GranularityKey)
^
|___Advanced language feature: reflective call
在类型选择中出现了一些反射调用的想法信号T#T#GranularityKey
。
您能解释一下这里会发生什么反射调用吗?那么它实际上是类型安全的吗?
也许,因为下一个 type Aux[TT <: Granularity] = Test{ type T = TT }
- 基本上你在这里说有一些 Test
应该在其中定义类型别名 T
。我认为此处的编译器逻辑类似于 Scala 实现中的 Duck Typing。例如,您可以定义 type Foo{ def bar(): Unit}
并尝试下一个
class FooImpl {
def bar(): Unit = println("Bar")
}
val foo: Foo = new FooImpl
foo.bar()
如你所见FooImpl
没有继承任何东西,但仍然可以分配给类型Foo
,因为它满足具有方法bar
的条件,但由于JVM限制或字节- 代码限制 - foo.bar()
调用将是反射式的,意思是 Java 反射 API。但是,尽管如此,这种方法是完全类型安全的。
也许,Idea 因此也认为 Test
特征中的类型别名 T
将通过反射 API.