为什么 Scala 案例类字段不反映为公共? [英] Why don't Scala case class fields reflect as public?
问题描述
我一直将 case 类的构造函数参数理解为定义公共 val.
I've always understood the constructor arguments of case classes as defining public vals.
但是,当我反映字段时,isPublic 方法出现错误.任何想法为什么?
However, when I reflect the fields, the isPublic method comes up false. Any ideas why?
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
推荐答案
原因是您查询的 num
和 name
的实际值确实是私有的.对于案例类(以及具有公共类参数的类),类参数被实现为带有公共访问器(为您自动生成)的私有字段.
The reason is that the actual values that you queried for num
and name
are indeed private. For case classes (and classes with public class parameters), class parameters are implemented as private fields with public accessors (which are generated automatically for you).
如果您想使用 Scala 反射来获取表示给定字段的公共访问器的符号,您可以简单地执行:
If you want to use Scala Reflection to obtain a symbol representing the public accessor for a given field, you can simply do:
scala> tpe.member("name": TermName)
res02: reflect.runtime.universe.Symbol = value name
如果你这样做,你可以看到它是一个公共访问器:
You can see that it's a public accessor if you do:
scala> tpe.member("name": TermName).isPublic
res03: Boolean = true
scala> tpe.member("name": TermName).isMethod
res04: Boolean = true
在您的情况下,您过滤掉了访问者,只留下了实际的(私有)字段.您可以通过使用 isAccessor
(或 isGetter
)而不是 isVal
进行检查来更改上面的代码以实现您想要的.
In your case, you filtered out the accessors, leaving only the actual (private) fields. You can change your code from above to achieve what you want by instead checking with isAccessor
(or isGetter
) instead of 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
这篇关于为什么 Scala 案例类字段不反映为公共?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!