2010-04-16 8 views
45

Dato:Come posso ottenere facilmente il nome di una classe di case Scala?

case class FirstCC { 
    def name: String = ... // something that will give "FirstCC" 
} 
case class SecondCC extends FirstCC 
val one = FirstCC() 
val two = SecondCC() 

Come posso ottenere "FirstCC" da one.name e "SecondCC" da two.name?

+0

non fa il metodo toString di classi case hanno il loro nome (e parametri)? –

+0

'FirstCC.toString' restituisce' "" ' – pr1001

+1

Tramite probabilmente si intende' one.toString' ... – pr1001

risposta

67
def name = this.getClass.getName 

Oppure, se si desidera solo il nome senza il pacchetto:

def name = this.getClass.getSimpleName 

vedere la documentazione java.lang.Class per ulteriori informazioni.

+17

Si noti, tuttavia, che' getSimpleName' a volte può lanciare 'java.lang.InternalError: nome classe malformato', ad esempio quando lo si chiama sulla classe di un oggetto. – pr1001

+1

Dal 1.5 puoi anche usare 'getCanonicalName' – Benoit

+4

getSimpleName e getCannonicalName sono ancora bacati, c'è un ticket in corso. https://issues.scala-lang.org/browse/SI-2034 (ed è un problema chiuso-come-duplicato https://issues.scala-lang.org/browse/SI-5425) – Lucas

11
def name = this.getClass.getName 
+0

Grazie, non sapevo di 'getName'. Molto meglio di 'toString'. – pr1001

12
class Example { 
    private def className[A](a: A)(implicit m: Manifest[A]) = m.toString 
    override def toString = className(this) 
} 
+0

Qual è il vantaggio di questo approccio (solo 2.8) su 'this.getClass.getName'? – pr1001

+5

@ pr1001 Conserverà i parametri del tipo se li hai. –

+0

C'è un modo per recuperare il nome della classe senza la parte del pacchetto (come nel caso di 'getSimpleName')? Trovo la tua risposta un modo molto carino per superare l'eccezione java.lang.InternalError: Nome classe malformato in caso di oggetti nidificati –

17

È possibile utilizzare la proprietà productPrefix della classe caso:

case class FirstCC { 
    def name = productPrefix 
} 
case class SecondCC extends FirstCC 
val one = FirstCC() 
val two = SecondCC() 

one.name 
two.name 

N.B. Se si passa a Scala 2,8 estendendo una classe case sono state deprecato, e bisogna non dimenticare la sinistra e genitore destra ()

5

Ecco una funzione Scala che genera una stringa leggibile da qualsiasi tipo, recursing del tipo parametri:

https://gist.github.com/erikerlandson/78d8c33419055b98d701

import scala.reflect.runtime.universe._ 

object TypeString { 

    // return a human-readable type string for type argument 'T' 
    // typeString[Int] returns "Int" 
    def typeString[T :TypeTag]: String = { 
    def work(t: Type): String = { 
     t match { case TypeRef(pre, sym, args) => 
     val ss = sym.toString.stripPrefix("trait ").stripPrefix("class ").stripPrefix("type ") 
     val as = args.map(work) 
     if (ss.startsWith("Function")) { 
      val arity = args.length - 1 
      "(" + (as.take(arity).mkString(",")) + ")" + "=>" + as.drop(arity).head 
     } else { 
      if (args.length <= 0) ss else (ss + "[" + as.mkString(",") + "]") 
     } 
     } 
    } 
    work(typeOf[T]) 
    } 

    // get the type string of an argument: 
    // typeString(2) returns "Int" 
    def typeString[T :TypeTag](x: T): String = typeString[T] 
} 
Problemi correlati