为什么 Scala 案例类字段不反映为公共? [英] Why don't Scala case class fields reflect as public?

查看:45
本文介绍了为什么 Scala 案例类字段不反映为公共?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直将 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

推荐答案

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

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆