scala – 为什么不能优化隐式转换的这种情况?
发布时间:2020-12-16 18:51:02 所属栏目:安全 来源:网络整理
导读:为什么 Scala无法优化以下内容: 一个. implicit def whatever[A](a: A) = new { ... } 至: 湾 class some$generated$name(a: A) { ...}implicit def whatever[A](a: A) = new some$generated$name(a) ? 为什么在这种情况下必须使用结构类型?我希望Scala
为什么
Scala无法优化以下内容:
一个. implicit def whatever[A](a: A) = new { ... } 至: 湾 class some$generated$name(a: A) { ... } implicit def whatever[A](a: A) = new some$generated$name(a) ? 为什么在这种情况下必须使用结构类型?我希望Scala编译器能够执行这种优化,因为写入样式b太丑了(因为,1.逻辑的局部性丢失了,2.你必须不必要地为这些额外的显式类创建名称),而且a的性能要差得多比b. 解决方法
我认为它可以,并且这可以通过编译器插件完成,看起来像
@extension implicit def whatever[A](a: A) = new { ... } 但我不知道是否还有人写过这样的插件…… 更新: 如果我编译这个文件: object Main { implicit def option[A](a: A) = new { def id = a } def foo(x: String) = x.id } 并且为foo反编译代码,仍然涉及反射: F:MyProgrammingraw>javap -c Main$ Compiled from "Main.scala" public final class Main$extends java.lang.Object implements scala.ScalaObject{ public static final Main$MODULE$; public static {}; Code: 0: new #9; //class Main$ 3: invokespecial #12; //Method "<init>":()V 6: return public static java.lang.reflect.Method reflMethod$Method1(java.lang.Class); Code: 0: getstatic #20; //Field reflPoly$Cache1:Ljava/lang/ref/SoftReference; 3: invokevirtual #27; //Method java/lang/ref/SoftReference.get:()Ljava/lang/Object; 6: checkcast #29; //class scala/runtime/MethodCache 9: ifnonnull 29 12: new #23; //class java/lang/ref/SoftReference 15: dup 16: new #31; //class scala/runtime/EmptyMethodCache 19: dup 20: invokespecial #32; //Method scala/runtime/EmptyMethodCache."<init>":()V 23: invokespecial #35; //Method java/lang/ref/SoftReference."<init>":(Ljava/lang/Object;)V 26: putstatic #20; //Field reflPoly$Cache1:Ljava/lang/ref/SoftReference; 29: getstatic #20; //Field reflPoly$Cache1:Ljava/lang/ref/SoftReference; 32: invokevirtual #27; //Method java/lang/ref/SoftReference.get:()Ljava/lang/Object; 35: checkcast #29; //class scala/runtime/MethodCache 38: aload_0 39: invokevirtual #38; //Method scala/runtime/MethodCache.find:(Ljava/lang/Class;)Ljava/lang/r eflect/Method; 42: astore_1 43: aload_1 44: ifnull 49 47: aload_1 48: areturn 49: aload_0 50: ldc #40; //String id 52: getstatic #42; //Field reflParams$Cache1:[Ljava/lang/Class; 55: invokevirtual #48; //Method java/lang/Class.getMethod:(Ljava/lang/String;[Ljava/lang/Class ;)Ljava/lang/reflect/Method; 58: astore_1 59: new #23; //class java/lang/ref/SoftReference 62: dup 63: getstatic #20; //Field reflPoly$Cache1:Ljava/lang/ref/SoftReference; 66: invokevirtual #27; //Method java/lang/ref/SoftReference.get:()Ljava/lang/Object; 69: checkcast #29; //class scala/runtime/MethodCache 72: aload_0 73: aload_1 74: invokevirtual #52; //Method scala/runtime/MethodCache.add:(Ljava/lang/Class;Ljava/lang/ref lect/Method;)Lscala/runtime/MethodCache; 77: invokespecial #35; //Method java/lang/ref/SoftReference."<init>":(Ljava/lang/Object;)V 80: putstatic #20; //Field reflPoly$Cache1:Ljava/lang/ref/SoftReference; 83: aload_1 84: areturn public java.lang.Object option(java.lang.Object); Code: 0: new #59; //class Main$$anon$1 3: dup 4: aload_1 5: invokespecial #60; //Method Main$$anon$1."<init>":(Ljava/lang/Object;)V 8: areturn public java.lang.String foo(java.lang.String); Code: 0: aload_0 1: aload_1 2: invokevirtual #69; //Method option:(Ljava/lang/Object;)Ljava/lang/Object; 5: astore_2 6: aconst_null 7: astore_3 8: aload_2 9: invokevirtual #75; //Method java/lang/Object.getClass:()Ljava/lang/Class; 12: invokestatic #77; //Method reflMethod$Method1:(Ljava/lang/Class;)Ljava/lang/reflect/Metho d; 15: aload_2 16: iconst_0 17: anewarray #71; //class java/lang/Object 20: invokevirtual #83; //Method java/lang/reflect/Method.invoke:(Ljava/lang/Object;[Ljava/lang /Object;)Ljava/lang/Object; 23: astore_3 24: aload_3 25: checkcast #85; //class java/lang/String 28: checkcast #85; //class java/lang/String 31: areturn 32: astore 4 34: aload 4 36: invokevirtual #91; //Method java/lang/reflect/InvocationTargetException.getCause:()Ljava/l ang/Throwable; 39: athrow Exception table: from to target type 8 24 32 Class java/lang/reflect/InvocationTargetException } 与之比较 object Main2 { class Whatever[A](a: A) { def id = a } implicit def option[A](a: A) = new Whatever(a) def foo(x: String) = x.id } 并反编译: F:MyProgrammingraw>javap -c Main2$ Compiled from "Main2.scala" public final class Main2$extends java.lang.Object implements scala.ScalaObject{ public static final Main2$MODULE$; public static {}; Code: 0: new #9; //class Main2$ 3: invokespecial #12; //Method "<init>":()V 6: return public Main2$Whatever option(java.lang.Object); Code: 0: new #16; //class Main2$Whatever 3: dup 4: aload_1 5: invokespecial #20; //Method Main2$Whatever."<init>":(Ljava/lang/Object;)V 8: areturn public java.lang.String foo(java.lang.String); Code: 0: aload_0 1: aload_1 2: invokevirtual #30; //Method option:(Ljava/lang/Object;)LMain2$Whatever; 5: invokevirtual #34; //Method Main2$Whatever.id:()Ljava/lang/Object; 8: checkcast #36; //class java/lang/String 11: areturn } F:MyProgrammingraw>javap -c Main2$Whatever Compiled from "Main2.scala" public class Main2$Whatever extends java.lang.Object implements scala.ScalaObject{ public java.lang.Object id(); Code: 0: aload_0 1: getfield #14; //Field a:Ljava/lang/Object; 4: areturn public Main2$Whatever(java.lang.Object); Code: 0: aload_0 1: aload_1 2: putfield #14; //Field a:Ljava/lang/Object; 5: aload_0 6: invokespecial #22; //Method java/lang/Object."<init>":()V 9: return } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |