2010-04-16 13 views
45

Gegeben:Wie kann ich leicht den Namen einer Scala-Fallklasse bekommen?

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

Wie kann ich "FirstCC" von one.name und "SecondCC" von two.name bekommen?

+0

verfügen nicht über die toString Methode der Fallklassen ihre Namen (und Parameter)? –

+0

'FirstCC.toString' return' "" ' – pr1001

+1

Durch Sie wahrscheinlich gemeint' one.toString' ... – pr1001

Antwort

67
def name = this.getClass.getName 

Oder wenn Sie nur den Namen ohne das Paket:

def name = this.getClass.getSimpleName 

finden Sie in der Dokumentation von java.lang.Class für weitere Informationen.

+17

Beachten sie jedoch, dass' getSimpleName' manchmal werfen kann 'java.lang.InternalError: Malformed Klasse name', zum Beispiel, wenn es auf die Klasse eines Objekts aufrufen. – pr1001

+1

Seit 1.5 können Sie auch 'getCanonicalName' verwenden – Benoit

+4

getSimpleName und getCannonicalName sind immer noch fehlerhaft, es gibt ein laufendes Ticket. https://issues.scala-lang.org/browse/SI-2034 (und es ist geschlossen-as-Duplikat Ausgabe https://issues.scala-lang.org/browse/SI-5425) – Lucas

11
def name = this.getClass.getName 
+0

Danke, ich wusste nicht über 'getName'. Viel besser als 'toString'. – pr1001

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

Was ist der Vorteil dieses (nur 2.8) Ansatzes gegenüber 'this.getClass.getName'? – pr1001

+5

@ pr1001 Es wird Typ Parameter beibehalten, wenn Sie sie haben. –

+0

Gibt es eine Möglichkeit, den Klassennamen ohne Paketteil von dort abzurufen (genau wie im Fall von 'getSimpleName')? Ich finde Ihre Antwort sehr schöne Art und Weise zu überwinden 'java.lang.InternalError: Malformed Klasse name' Ausnahme im Fall von verschachtelten Objekten –

17

können Sie die Eigenschaft productPrefix der Fall Klasse:

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

one.name 
two.name 

N. B. Wenn Sie scala passieren 2.8 einen Fall-Klasse aufgegeben wurden erstreckt, und Sie haben nicht die linken und rechten Eltern ()

5

Hier vergessen ist eine Scala-Funktion, die eine für Menschen lesbare Zeichenfolge aus jeder Art erzeugt, auf Typ Rekursion Parameter:

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] 
} 
Verwandte Themen