有没有办法在Scala中使用命名字段的元组,类似于C#中的匿名类?
发布时间:2020-12-16 09:19:04 所属栏目:安全 来源:网络整理
导读:见: Can I specify a meaningful name for an anonymous class in C#? 在C#中可以写: var e = new { ID = 5,Name= "Prashant" };assertEquals( 5,e.ID ) 但是在Scala我最终写道: var e = (5,"Prashant")assertEquals( 5,e._1 ) Scala通过使用泛型(与C#一
见:
Can I specify a meaningful name for an anonymous class in C#?
在C#中可以写: var e = new { ID = 5,Name= "Prashant" }; assertEquals( 5,e.ID ) 但是在Scala我最终写道: var e = (5,"Prashant") assertEquals( 5,e._1 ) Scala通过使用泛型(与C#一样)来维护类型安全性,但是丢失每个字段名称的可读性,例如我使用“_1”而不是“ID”. 在Scala里有什么吗? 解决方法object T { def main(args: Array[String]) { val e = new { var id = 5; var name = "Prashant" } assert(e.id == 5) } } 好的,让我们清楚一些东西.这在Scala 2.7和Scala 2.8中使用反射,因为在这种情况下,e的类型是Scala通过反射处理的结构类型.这是生成的代码,在清理时间(scalac -Xprint:cleanup): package <empty> { final class T extends java.lang.Object with ScalaObject { private <synthetic> <static> var reflMethod$Cache1: java.lang.reflect.Method = null; private <synthetic> <static> var reflClass$Cache1: java.lang.Class = null; <synthetic> <static> def reflMethod$Method1(x$1: java.lang.Class): java.lang.reflect.Method = { if (T.this.reflMethod$Cache1.eq(null).||(T.this.reflClass$Cache1.ne(x$1))) { T.this.reflMethod$Cache1 = x$1.getMethod("id",Array[java.lang.Class]{}); T.this.reflClass$Cache1 = x$1; () }; T.this.reflMethod$Cache1 }; @remote def $tag(): Int = scala.ScalaObject$class.$tag(T.this); def main(args: Array[java.lang.String]): Unit = { val e: java.lang.Object = { new T$$anon$1() }; scala.this.Predef.assert(scala.Int.unbox({ var exceptionResult1: java.lang.Object = _; try { exceptionResult1 = T.reflMethod$Method1(e.getClass()).invoke(e,Array[java.lang.Object]{}) } catch { case ($1$@ (_: java.lang.reflect.InvocationTargetException)) => { exceptionResult1 = throw $1$.getCause() } }; exceptionResult1 }.$asInstanceOf[java.lang.Integer]()).==(5)) }; def this(): object T = { T.super.this(); () } }; final class T$$anon$1 extends java.lang.Object { private[this] var id: Int = _; <accessor> def id(): Int = T$$anon$1.this.id; <accessor> def id_=(x$1: Int): Unit = T$$anon$1.this.id = x$1; private[this] var name: java.lang.String = _; <accessor> def name(): java.lang.String = T$$anon$1.this.name; <accessor> def name_=(x$1: java.lang.String): Unit = T$$anon$1.this.name = x$1; def this(): T$$anon$1 = { T$$anon$1.this.id = 5; T$$anon$1.this.name = "Prashant"; T$$anon$1.super.this(); () } } } 有一些缓存正在进行,但如果我在id和name之间进行交替,就会使缓存失效. Scala 2.8还有反思,也是缓存,但它使用更有效的缓存技术,这应该提供更好的整体性能.作为参考,这里是Scala 2.8的清理: package <empty> { final class T extends java.lang.Object with ScalaObject { final private <synthetic> <static> var reflParams$Cache1: Array[java.lang.Class] = Array[java.lang.Class]{}; @volatile private <synthetic> <static> var reflPoly$Cache1: scala.runtime.MethodCache = new scala.runtime.EmptyMethodCache(); <synthetic> <static> def reflMethod$Method1(x$1: java.lang.Class): java.lang.reflect.Method = { var method1: java.lang.reflect.Method = T.reflPoly$Cache1.find(x$1); if (method1.ne(null)) return method1 else { method1 = x$1.getMethod("id",T.reflParams$Cache1); T.reflPoly$Cache1 = T.reflPoly$Cache1.add(x$1,method1); return method1 } }; def main(args: Array[java.lang.String]): Unit = { val e: java.lang.Object = { new T$$anon$1() }; scala.this.Predef.assert(scala.Int.unbox({ val qual1: java.lang.Object = e; { var exceptionResult1: java.lang.Object = _; try { exceptionResult1 = T.reflMethod$Method1(qual1.getClass()).invoke(qual1,Array[java.lang.Object]{}) } catch { case ($1$@ (_: java.lang.reflect.InvocationTargetException)) => { exceptionResult1 = throw $1$.getCause() } }; exceptionResult1 }.$asInstanceOf[java.lang.Integer]() }).==(5)) }; def this(): object T = { T.reflParams$Cache1 = Array[java.lang.Class]{}; T.reflPoly$Cache1 = new scala.runtime.EmptyMethodCache(); T.super.this(); () } }; final class T$$anon$1 extends java.lang.Object { private[this] var id: Int = _; <accessor> def id(): Int = T$$anon$1.this.id; <accessor> def id_=(x$1: Int): Unit = T$$anon$1.this.id = x$1; private[this] var name: java.lang.String = _; <accessor> def name(): java.lang.String = T$$anon$1.this.name; <accessor> def name_=(x$1: java.lang.String): Unit = T$$anon$1.this.name = x$1; def this(): T$$anon$1 = { T$$anon$1.super.this(); T$$anon$1.this.id = 5; T$$anon$1.this.name = "Prashant"; () } } } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |