2013-03-31 25 views
6

我一直理解case類的構造函數參數作爲定義公共val。爲什麼斯卡拉案例類字段沒有反映爲公共?

但是,當我反映字段時,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

斯卡拉不自動生成私有實例變量的公共訪問器方法嗎?我不確定實現細節應該通過反思來揭示,但也許看着這些方法會讓你更進一步。 – copumpkin

回答

11

的原因是你查詢了numname的實際值確實是私有的。對於案例類(以及具有公共類參數的類),類參數被實現爲具有公共訪問器(爲您自動生成)的私有字段。

如果你想使用Scala的反射來獲得代表了某一領域的公共訪問的象徵,你可以簡單地做:

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 
+0

Eugene Burmako昨天告訴我的一件事是Scala反射試圖讓用戶免於意識到這種性質的「實現細節」。這對我來說是有意義的,它是以這種方式實現的,但是這是Scala反射的正確抽象級別嗎?雖然也許史蒂夫沃爾德曼的代碼試圖過於具體,並且您在答案開始時提出的簡單訪問器正在按照我的建議進行...... – copumpkin

+0

謝謝,非常清晰和完整的回覆! –

+1

四處遊蕩,是否公平地斷定vals從不公開,只有他們自動生成的訪問者可能是?即使在非案例課程中,發佈者反映爲非公開,而訪問者反映爲公開。這得到了copumpkin的問題:我是否反思了實現細節?在val作爲pvt Java字段+自動生成的訪問器,而不是本機Scala構造?我很高興能夠生活在反映「vals」是潛在領域的概念中,知名度和訪問權限應該與訪問者掛鉤。但這可能會更好地記錄。再次感謝您的工作,並感謝您的迴應! –