为什么Scala案例类字段不反映为公开?

时间:2013-03-31 13:59:34

标签: scala

我总是将case类的构造函数参数理解为定义公共值。

但是,当我反映字段时,isPublic方法出现错误。有什么想法吗?

scala> class Test( val name : String, val num : Int )
defined class Test

scala> import scala.reflect.runtime.universe._
import scala.reflect.runtime.universe._

scala> val tpe = typeOf[Test]
tpe: reflect.runtime.universe.Type = Test

scala> def checkValVisibility( t : Type ) = {
     | t.members
     |   .filter( _.isTerm )
     |   .map( _.asTerm )
     |   .filter( _.isVal )
     |   .map( memb => "Val " + memb.name.toString.trim + " is public? " + memb.isPublic )
     |   .mkString("\n")
     | }
checkValVisibility: (t: reflect.runtime.universe.Type)String

scala> checkValVisibility( tpe )
res2: String = 
Val num is public? false
Val name is public? false

1 个答案:

答案 0 :(得分:12)

原因是您查询numname的实际值确实是私有的。对于案例类(以及具有公共类参数的类),类参数实现为具有公共访问器的私有字段(为您自动生成)。

如果您想使用Scala Reflection获取代表给定字段的公共访问者的符号,您只需执行以下操作:

scala> tpe.member("name": TermName)
res02: reflect.runtime.universe.Symbol = value name

如果你这样做,你可以看到它是一个公共访问者:

scala> tpe.member("name": TermName).isPublic
res03: Boolean = true

scala> tpe.member("name": TermName).isMethod
res04: Boolean = true

在您的情况下,您过滤了访问者,只留下实际(私有)字段。您可以通过isAccessor(或isGetter)代替isVal来更改上面的代码,以实现您的目标。

scala> def checkValVisibility( t : Type ) = {
     |   t.members
     |    .filter( _.isTerm )
     |    .map( _.asTerm )
     |    .filter( _.isAccessor )
     |    .map( memb => "Val " + memb.name.toString.trim + " is public? " + memb.isPublic )
     |    .mkString("\n")
     | }
checkValVisibility: (t: reflect.runtime.universe.Type)String

scala> checkValVisibility(tpe)
res05: String = 
Val num is public? true
Val name is public? true