2010-04-16 5 views
45

Étant donné:Comment puis-je obtenir facilement le nom d'une classe Scala?

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

Comment puis-je obtenir "FirstCC" de one.name et "SecondCC" de two.name?

+0

ne pas la méthode toString des classes de cas ont leur nom (et les paramètres)? –

+0

'FirstCC.toString' renvoie' "" ' – pr1001

+1

Grâce à vous probablement signifié' one.toString' ... – pr1001

Répondre

67
def name = this.getClass.getName 

Ou si vous voulez seulement le nom sans le paquet:

def name = this.getClass.getSimpleName 

Voir la documentation de java.lang.Class pour plus d'informations.

+17

Notez, cependant, que' getSimpleName' peut parfois lancer 'java.lang.InternalError: Malformed class name', par exemple en l'appelant sur la classe d'un objet. – pr1001

+1

Depuis la version 1.5, vous pouvez aussi utiliser 'getCanonicalName' – Benoit

+4

getSimpleName et getCannonicalName sont toujours buggés, il y a un ticket en cours. https://issues.scala-lang.org/browse/SI-2034 (et c'est un numéro fermé-comme-dupliqué https://issues.scala-lang.org/browse/SI-5425) – Lucas

11
def name = this.getClass.getName 
+0

Merci, je ne connaissais pas 'getName'. Beaucoup mieux que 'toString'. – pr1001

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

Quel est l'avantage de cette approche (2.8 seulement) sur 'this.getClass.getName'? – pr1001

+5

@ pr1001 Il conservera les paramètres de type si vous les avez. –

+0

Existe-t-il un moyen d'extraire le nom de la classe sans la partie du paquet (comme dans le cas de 'getSimpleName')? Je trouve ta réponse très sympa pour surmonter l'exception 'java.lang.InternalError: Malformed class name' dans le cas d'objets imbriqués –

17

Vous pouvez utiliser la propriété productPrefix de la classe de cas:

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

one.name 
two.name 

N.B. Si vous passez à scala 2.8 l'extension d'une classe de cas ont été désapprouvée, et vous devez ne pas oublier la gauche et parent droit ()

5

Voici une fonction Scala qui génère une chaîne lisible par l'homme de tout type, récursion le type paramètres:

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] 
} 
Questions connexes