如何以編程方式確定給定的類是案例類還是簡單類?如何以編程方式確定該類是案例類還是簡單類?
11
A
回答
2
目前(2011年),你可以使用反射來看看這個類實現接口scala.Product
:
scala> def isCaseClass(o: AnyRef) = o.getClass.getInterfaces.find(_ == classOf[scala.Product]) != None
isCaseClass: (o: AnyRef)Boolean
scala> isCaseClass(Some(1))
res3: Boolean = true
scala> isCaseClass("")
res4: Boolean = false
這只是一個近似值 - 你可以進一步去檢查它是否有copy
方法,如果它實現Serializable
,如果它具有與適當的apply
或unapply
方法伴侶對象 - 在本質上,檢查所有來自使用反射的情況下,預期類的東西。
下一個版本中的scala反射包應該使case類檢測更容易和更精確。
編輯:
可以現在使用新的Scala庫的思考了 - 看其他答案。
2
如果您的意思是:我可以通過編程確定類是案例類還是非案例類,答案是否定的,但您可以進行近似處理。案例類只是一個編譯器黑客,他們告訴編譯器創建某些方法等。在最終的字節碼中,普通類和案例類沒有區別。
從How does a case class differ from a normal class?
- 你可以做模式上的匹配,
- 可以構造這些類的實例,而無需使用新的 關鍵字,
- 所有構造函數的參數是從外部利用訪問 自動生成的存取函數,
- toString方法被自動重新定義爲打印名稱 案例分類及其所有參數
- equals方法會自動重新定義,以在結構上而不是按身份比較兩個相同案例類的 實例。
- hashCode方法被自動重新定義爲使用的構造器參數的 散列碼。
所以,你可以通過只定義了正確的方法&同伴對象自己真正創建一個案例類。
有關如何找出類可能是案例類的想法,請查看axel22的答案。
16
使用新斯卡拉反射API:
scala> class B(v: Int)
defined class B
scala> case class A(v: Int)
defined class A
scala> def isCaseClassOrWhat_?(v: Any): Boolean = {
| import reflect.runtime.universe._
| val typeMirror = runtimeMirror(v.getClass.getClassLoader)
| val instanceMirror = typeMirror.reflect(v)
| val symbol = instanceMirror.symbol
| symbol.isCaseClass
| }
isCaseClassOrWhat_$qmark: (v: Any)Boolean
scala> class CaseClassWannabe extends Product with Serializable {
| def canEqual(that: Any): Boolean = ???
| def productArity: Int = ???
| def productElement(n: Int): Any = ???
| }
defined class CaseClassWannabe
scala> isCaseClassOrWhat_?("abc")
res0: Boolean = false
scala> isCaseClassOrWhat_?(1)
res1: Boolean = false
scala> isCaseClassOrWhat_?(new B(123))
res2: Boolean = false
scala> isCaseClassOrWhat_?(A(321))
res3: Boolean = true
scala> isCaseClassOrWhat_?(new CaseClassWannabe)
res4: Boolean = false
相關問題
- 1. 工廠類應該是單例還是靜態方法?
- 2. 簡單助手方法應該是私有實例方法,類類還是其他所有方法?
- 3. 如何確定`this`是類還是對象的實例?
- 4. 如何以編程方式確定特定進程是32位還是64位
- 5. MouseEvent是類還是類的實例?
- 6. 是元類中的類還是實例?
- 7. 類名應該反映類本身還是類的實例?
- 8. 確定類型是引用類型還是值類型
- 9. iOS:以編程方式確定WiFi連接是2.4Ghz還是5Ghz
- 10. 類方法可以是內聯方式還是靜態方式?
- 11. 是返回類型實例還是值簡單分配
- 12. 如何在c#中以編程方式確定類型是否接受空值?
- 13. 該方法*****是不確定的類型*******
- 14. 確定參數是類還是協議
- 15. 如何以編程方式確定我的處理器類型?
- 16. 演員案例類簡單的例子
- 17. 如何確定System.Type是自定義類型還是框架類型?
- 18. 如何以編程方式編譯和實例化Java類?
- 19. Ruby 1.8 vs. 1.9:確定Ruby單例類是否是另一個類的子類
- 20. 以編程方式指定Fogbugz案例
- 21. 我應該使用EventArgs還是簡單的數據類型?
- 22. 選擇正確的子類以編程方式實例化
- 23. 我們所有的模型類應該是案例類嗎?
- 24. 如何確定一個類是否是其他類的子類?
- 25. 如何確定T是泛型中的值類型還是引用類?
- 26. 如何確定某個屬性是位於原始類還是繼承類?
- 27. 如何確定mysql數據庫的類型:是InnoDB還是MyISAM?
- 28. Python:如何確定屬性(按名稱)是類還是實例屬性?
- 29. Excel確定單元格的數據類型是DateTime還是Int
- 30. 確定類x是否從類y派生的最簡單方法? (C#)
謝謝你,axel22。這是我的問題的解決方案。我希望開發人員儘快添加這種Scala方法。 Сlass實現接口scala.Product - 這是一個充分的條件嗎? – DimParf
不,沒有足夠的條件來檢查這個(afaik)。您無法檢查原始代碼中是否存在「case」修飾符,僅限於由「case」修飾符生成的方法。正如我上面寫的,整個事情只是一個近似值。 – axel22