2012-06-28 44 views
6

Với phương thức isInstanceOf, người ta có thể kiểm tra loại đối tượng. Ví dụ:Làm thế nào để hiển thị tất cả các loại đối tượng (trong Scala)?

scala> val i: Int = 5 
i: Int = 5 

scala> val a: Any = i 
a: Any = 5 

scala> a.isInstanceOf[Any] 
res0: Boolean = true 

scala> a.isInstanceOf[Int] 
res1: Boolean = true 

scala> a.isInstanceOf[String] 
res2: Boolean = false 

Làm cách nào để hiển thị tất cả các loại đối tượng (nếu có thể?)?

Trả lời

6

Bạn có thể làm được điều này khá dễ dàng trong 2.10 (M4 hoặc mới hơn):

import scala.reflect.runtime.universe._ 

def superTypes(t: Type): Set[Type] = 
    (t.parents ++ t.parents.flatMap(superTypes)).toSet 

def allTypes[A](a: A)(implicit tag: TypeTag[A]) = superTypes(tag.tpe) + tag.tpe 

nào cho chúng ta như sau:

scala> allTypes(1).foreach(println) 
AnyVal 
Any 
NotNull 
Int 

scala> allTypes("1").foreach(println) 
String 
Any 
Object 
Comparable[String] 
CharSequence 
java.io.Serializable 

scala> allTypes(List("1")).foreach(println) 
scala.collection.LinearSeq[String] 
scala.collection.GenSeq[String] 
scala.collection.IterableLike[String,List[String]] 
scala.collection.GenIterable[String] 
scala.collection.GenTraversableLike[String,Iterable[String]] 
... 

Bạn sẽ có một thời gian khó khăn hơn nhiều cố gắng làm bất cứ điều gì như thế này trước 2.10.

+0

Cảm ơn bạn, với 2.10 có vẻ thực sự khá dễ dàng. Bạn có biết liệu có thể liệt kê tất cả các loại trong phiên bản trước 2.10 không? –

+0

[Manifests] (http://www.scala-lang.org/api/current/scala/reflect/Manifest.html) không thực sự được thiết kế để hỗ trợ loại điều này. Bạn có thể sử dụng [Java Reflection API] (http://docs.oracle.com/javase/tutorial/reflect/index.html) để có được các superclass, các giao diện được thực hiện, vv, nhưng điều đó rất khác với việc nhận _types_. –

1

Đây là một giải pháp khác, sử dụng phương pháp baseType để sửa lại thông số loại.

import scala.reflect.runtime.universe._ 

def typesOf[T : TypeTag](v: T): List[Type] = 
    typeOf[T].baseClasses.map(typeOf[T].baseType) 

Ví dụ:

scala> typesOf("1") foreach println 
String 
CharSequence 
Comparable[String] 
java.io.Serializable 
Object 
Any 
+0

'baseClasses' rất tiện dụng, nhưng không phải là _types_, tất nhiên, đó là câu hỏi được hỏi. Nó cũng đáng chú ý rằng điều này sẽ không làm việc trước 2,10. –

+0

@TravisBrown Câu hỏi cho biết _display_ tất cả các loại. Trả về 'baseClasses' là' Symbol' cho các kiểu. Bạn có thể gọi 'asTypeSymbol' trên tất cả chúng, hoặc, tất nhiên,' .asType' hoặc '.typeSignature'. –

+0

Nhưng hãy nói ví dụ rằng bạn muốn các loại 'List (" 1 ")' sao cho bạn có thể biết liệu 'GenSeq [String]' là một trong số chúng (không sử dụng 'isInstanceOf' vì bất kỳ lý do gì). Một khi bạn đã sử dụng 'baseClasses' thì không có cách nào để lấy thông tin đó - tất cả những gì bạn có thể làm là lấy biểu tượng kiểu cho' GenSeq'. –

Các vấn đề liên quan