Come determinare a livello di codice se la classe data è una classe case o una classe semplice?Come determinare a livello di codice se la classe è una classe case o una classe semplice?
risposta
Attualmente (2011), è possibile utilizzare la reflection per scoprire se la classe implementa l'interfaccia 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
Questo è solo un'approssimazione - si potrebbe andare oltre e verificare se ha un metodo copy
, se implementa Serializable
, se ha un oggetto companion con un metodo appropriato apply
o unapply
, in sostanza, controlla tutti gli aspetti previsti da una classe di casi utilizzando la reflection.
Il pacchetto scala reflection in arrivo in una delle prossime versioni dovrebbe rendere più facile e più preciso il rilevamento della classe del case.
EDIT:
ora è possibile farlo utilizzando la nuova libreria di riflessione Scala - vedi altra risposta.
Se intendi: Posso determinare se una classe è una classe case o una classe non-case programmaticamente, la risposta è no, ma puoi fare un'approssimazione. Le classi di casi sono solo un hack del compilatore, dicono al compilatore di creare determinati metodi, ecc. Nel bytecode finale, non c'è differenza tra classi normali e classi di casi.
Da How does a case class differ from a normal class?
- Si può fare pattern matching su di esso,
- si può creare istanze di queste classi senza utilizzare la nuova parola chiave,
- Tutti gli argomenti del costruttore sono accessibili dall'esterno tramite funzioni di accesso generate automaticamente,
- Il metodo toString viene ridefinito automaticamente per stampare il nome della classe case e tutti i suoi argomenti,
- Il metodo di uguaglianza viene ridefinito automaticamente per confrontare due istanze della stessa classe di casi con la stessa classe di casi anziché con l'identità.
- Il metodo hashCode viene ridefinito automaticamente per utilizzare gli hash degli argomenti del costruttore.
modo da poter effettivamente creare una classe caso per definire soltanto i metodi corretti & compagno da soli oggetti.
Per un'idea su come scoprire se una classe potrebbe essere una classe di caso, osservare la risposta di axel22.
Usando nuova Scala riflessione 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. Determinare se una classe Java è una classe SE portatile
- 2. Come determinare se una classe estende un'altra classe in Java?
- 3. Come determinare se una classe è una sottoclasse di un'altra classe?
- 4. Come determinare se una classe Java è astratta per riflessione
- 5. Come determinare se una classe Java implementa una particolare interfaccia
- 6. Determinare se una funzione è autonoma o parte di una classe di tipo
- 7. confronto delle immagini a livello di codice - lib o classe
- 8. AS3 - Posso sapere se una classe implementa un'interfaccia (o è una sottoclasse di un'altra classe)?
- 9. python: determina se una classe è nidificata
- 10. Una classe base può determinare se una classe derivata ha sovrascritto un membro virtuale?
- 11. Django - come determinare se la classe del modello è astratta
- 12. Come determinare se T è un tipo di valore o una classe di riferimento in generale?
- 13. È una classe interna
- 14. Assegnare una sottoclasse di una classe generica a una classe super-di questa classe
- 15. classe di primo livello che si estende una classe interna
- 16. Eredita da una classe o una classe astratta
- 17. Come sapere se una classe discende da un'altra classe
- 18. Come verificare se una classe eredita un'altra classe senza istanziarla?
- 19. Verificare se una classe è polimorfica
- 20. `productElement (i)` su una classe di case usa la riflessione?
- 21. È possibile applicare a livello di codice una classe derivata per passare a se stessa in una classe base come tipo generico?
- 22. Come trovare se l'IType è una classe astratta
- 23. È una classe locale in un metodo di una classe un amico di questa classe?
- 24. Una classe può validarsi o creare un'altra classe per convalidarla?
- 25. Gerarchia classe case Scala
- 26. Come scrivere una semplice classe in C++?
- 27. Come rifattorizzare una classe interna statica in una classe di livello superiore in Eclipse?
- 28. C#: come stabilire se un oggetto è di una classe personalizzata o di una classe nativa di tipo /.NET?
- 29. C++ determina se la classe è paragonabile
- 30. Come si usa hasClass per rilevare se una classe NON è la classe che voglio?
Grazie, axel22. Questa è una soluzione al mio problema. Spero che gli sviluppatori aggiungano questo metodo di Scala il prima possibile. Сlass implementa l'interfaccia scala.Product - questa è una condizione sufficiente per questo? – DimParf
No, non ci sono condizioni sufficienti per controllare questo (afaik).Non è possibile verificare l'esistenza di un modificatore 'case' nel codice originale, solo per i metodi che vengono generati a causa del modificatore' case'. Come ho scritto sopra, il tutto è solo un'approssimazione. – axel22