如何专注于Scala中的类型投影?
问题陈述
考虑包含抽象类型成员A的类型T: trait T { type A } 我想创建一个以T0<:T作为类型参数的类,但专注于类型投影T0#A.例如,在下面,方法foo可以专门吗? class Foo[T0 <: T] { def foo(a: T0#A,f: T0#A => T0#A) = f(a) } 请注意,使用@specialized注释T0将无法获得所需的结果.在类型投影T#A上是否有一种专门研究foo的好方法? 有限的解决方案:从具有额外参数的专用父类继承 在这种特殊情况下,这是一种专注于T0#A的方法: trait SpecializedFoo[@specialized A0,T0 <: T] { def foo(a: A0,f: A0 => A0) = f(a) } class Foo2[T0 <: T] extends SpecializedFoo[T0#A,T0] 通过继承专门的父类SpecializedFoo,我们确保Foo2.foo是专用的. 验证专业化 为了验证Foo2.foo而不是Foo.foo是专用的,我们可以使用显式T调用它们,其中T#A是原始的Double, trait ExplicitT extends T { type A = Double } object Test { def test1 = (new Foo[ExplicitT]).foo(1.0,_ + 1.0) def test2 = (new Foo2[ExplicitT]).foo(1.0,_ + 1.0) } 可以使用命令“:javap -v Test”从REPL检查字节码, public double test1(); Code: Stack=4,Locals=1,Args_size=1 0: new #16; //class Foo 3: dup 4: invokespecial #18; //Method Foo."<init>":()V 7: dconst_1 8: invokestatic #24; //Method scala/runtime/BoxesRunTime.boxToDouble:(D)Ljava/lang/Double; 11: new #26; //class Test$$anonfun$test1$1 14: dup 15: invokespecial #27; //Method Test$$anonfun$test1$1."<init>":()V 18: invokevirtual #31; //Method Foo.foo:(Ljava/lang/Object;Lscala/Function1;)Ljava/lang/Object; 21: invokestatic #35; //Method scala/runtime/BoxesRunTime.unboxToDouble:(Ljava/lang/Object;)D 24: dreturn LineNumberTable: line 13: 0 public double test2(); Code: Stack=5,Args_size=1 0: new #38; //class Foo2 3: dup 4: invokespecial #39; //Method Foo2."<init>":()V 7: dconst_1 8: new #41; //class Test$$anonfun$test2$1 11: dup 12: invokespecial #42; //Method Test$$anonfun$test2$1."<init>":()V 15: invokeinterface #48,4; //InterfaceMethod SpecializedFoo.foo$mcD$sp:(DLscala/Function1;)D 20: dreturn LineNumberTable: line 14: 0 请注意,装箱出现在test1中,但不出现在test2中. 限制 编辑7/9上面的诀窍比我最初意识到的更有限.专门针对这种情况,它根本不起作用: trait T { type A def x: A def f: A => Double } class Foo[T0 <: T] { def foo(t: T0) = t.f(t.x) } 我认为没有理由(假设的)编译器原则上不能专注于A;通常,专用版本仅在编译时已知特定T#A时才可用.自然的实际解决方案是将A提升为T的类型参数,但我想知道我是否可以避免这种情况. 解决方法
我看不出那是怎么回事.在编译类时完成专业化,并且在那时,A是未知的.
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |