2010-04-16 41 views
45

Given:Làm thế nào tôi có thể dễ dàng có được tên của một trường hợp Scala?

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

Làm thế nào tôi có thể nhận được "FirstCC" từ one.name"SecondCC" từ two.name?

+0

không phương thức toString của trường hợp lớp có tên của họ (và các thông số)? –

+0

'FirstCC.toString' trả về' "" ' – pr1001

+1

Thông qua bạn có thể có nghĩa là' one.toString' ... – pr1001

Trả lời

67
def name = this.getClass.getName 

Hoặc nếu bạn muốn chỉ có tên mà không có đóng gói:

def name = this.getClass.getSimpleName 

Xem tài liệu của java.lang.Class để biết thêm thông tin.

+17

Lưu ý, tuy nhiên,' getSimpleName' đôi khi có thể ném 'java.lang.InternalError: Tên lớp không đúng định dạng ', ví dụ khi gọi nó trên lớp của một đối tượng. – pr1001

+1

Vì 1,5 bạn cũng có thể sử dụng 'getCanonicalName' – Benoit

+4

getSimpleName và getCannonicalName vẫn còn lỗi, có một vé đang diễn ra. https://issues.scala-lang.org/browse/SI-2034 (và vấn đề bị trùng lặp là https://issues.scala-lang.org/browse/SI-5425) – Lucas

11
def name = this.getClass.getName 
+0

Cảm ơn, tôi không biết về 'getName'. Tốt hơn nhiều so với 'toString'. – pr1001

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

Lợi ích của phương pháp này (2.8-only) trên 'this.getClass.getName' là gì? – pr1001

+5

@ pr1001 Nó sẽ bảo toàn các thông số kiểu nếu bạn có chúng. –

+0

Có cách nào để lấy tên lớp mà không có phần gói từ đó (giống như trong trường hợp 'getSimpleName')? Tôi tìm thấy câu trả lời của bạn rất hay để vượt qua 'java.lang.InternalError: Ngoại lệ tên lớp 'ngoại lệ trong trường hợp đối tượng lồng nhau –

17

Bạn có thể sử dụng thuộc tính productPrefix của lớp trường hợp:

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

one.name 
two.name 

N.B. Nếu bạn chuyển sang scala 2.8, mở rộng một lớp chữ hoa không được chấp nhận và bạn không được quên phụ huynh bên trái và bên phải ()

5

Đây là một hàm Scala tạo chuỗi có thể đọc được từ mọi loại, đệ quy theo loại thông số:

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] 
} 
Các vấn đề liên quan