2012-09-17 18 views
7

Với một khai báo kiểu, tôi có thể giải quyết đối số kiểu.Độ phân giải thời gian chạy của các đối số kiểu bằng cách sử dụng scala 2.10 reflection

scala> reflect.runtime.universe.typeOf[List[Int]] match {case x:TypeRef => x.args} 
res10: List[reflect.runtime.universe.Type] = List(Int) 

Đối với giá trị thời gian chạy, Phương pháp tương tự không hoạt động.

scala> reflect.runtime.currentMirror.reflect(List(42)).symbol.toType match {case x:TypeRef => x.args} 
res11: List[reflect.runtime.universe.Type] = List(B) 

Có cách nào để khắc phục loại tẩy xóa cho các giá trị được phản ánh không?

+0

Có thể bạn có thể tìm thấy giải pháp khả thi sau khi đọc [câu trả lời này] (http://stackoverflow.com/a/1094214/315306) – Raffaele

+0

@Raffaele. Cảm ơn bạn đã tham khảo. Thật không may câu hỏi (và câu trả lời) đối phó với trường hợp khi các loại được cụ thể và được biết đến trong thời gian biên dịch. Tệp kê khai không còn được dùng nữa và TypeTags (thay thế tệp kê khai) yêu cầu thẻ bê tông. –

+1

Sử dụng AbsTypeTag (trong RC1 được đổi tên thành WeakTypeTag). Thông tin thêm tại đây: http://stackoverflow.com/questions/12218641/scala-2-10-what-is-a-typetag-and-how-do-i-use-it –

Trả lời

6

Một ví dụ dựa trên kiến ​​thức TypeTag thu được từ đọc Scala: What is a TypeTag and how do I use it? đăng bởi Eugene Burmako trong các ý kiến ​​về câu hỏi của bạn:

import scala.reflect.runtime.universe._ 

object ScalaApplication { 
    def main(args: Array[String]) { 
    printType(List(42)) 
    printType(List("42")) 
    printType(List("42", 42)) 
    }  

    def printType[T : TypeTag](t: T) { 
    println(typeOf[T]) 
    } 
} 

Điều này sẽ cho kết quả:

$ scala ScalaApplication.scala 
List[Int] 
List[String] 
List[Any] 

[CẬP NHẬT 1:]

Tuy nhiên, nếu bạn muốn được nhận thức của các loại được gán cho một tài liệu tham khảo của loại Any bạn có thể phải lựa chọn một số loại loại wrapper biết:

import scala.reflect.runtime.universe._ 

object ScalaApplication { 
    def main(args: Array[String]) { 
    val anyWrapper = new AnyWrapper 

    List(1,2,3).foreach { i => 
     i match { 
     case 1 => anyWrapper.any = 42 
     case 2 => anyWrapper.any = "a string" 
     case 3 => anyWrapper.any = true 
     } 
     print(anyWrapper.any) 
     print(" has type ") 
     println(anyWrapper.typeOfAny) 
    } 
    } 

    class AnyWrapper { 
    private var _any: Any = null 
    private var _typeOfAny: Type = null 

    def any = _any 
    def typeOfAny = _typeOfAny 
    def any_=[T: TypeTag](a: T) = { 
     _typeOfAny = typeOf[T] 
     _any = a 
    } 

    } 
} 

Điều này sẽ cho kết quả:

$ scala ScalaApplication.scala 
42 has type Int 
a string has type String 
true has type Boolean 

Nhưng giải pháp này vẫn không bao gồm trường hợp loại tham chiếu không xác định tại thời gian biên dịch.

[UPDATE 2:]

Nếu loại được đúc một cách rõ ràng để tham khảo các loại Any, bạn có thể phải liệt kê tất cả các loại có thể trong một tuyên bố trận đấu để thu hồi các loại:

import scala.reflect.runtime.universe._ 

object ScalaApplication { 
    def main(args: Array[String]) { 

    List(1,2,3).foreach { i => 
     val any: Any = i match { 
     case 1 => 42.asInstanceOf[Any] 
     case 2 => "a string".asInstanceOf[Any] 
     case 3 => true.asInstanceOf[Any] 
     } 
     print(any) 
     print(" has type ") 
     println(matchType(any)) 
    } 
    } 

    def matchType(any: Any) = { 
    any match { 
     case a: Int => typeOf[Int] 
     case a: String => typeOf[String] 
     case a: Boolean => typeOf[Boolean] 
    } 
    } 
} 

Điều này sẽ cho kết quả:

$ scala ScalaApplication.scala 
42 has type Int 
a string has type String 
true has type Boolean 

Nhưng giải pháp này đòi hỏi bạn phải biết (một nd danh sách) tất cả các loại có thể mà bạn có thể nhận được trong giá trị any.

+0

Giải pháp này chỉ hoạt động khi loại được biết đến trong thời gian biên dịch. Đây là kết quả của printType trên một đối tượng mà giá trị không được biết trong thời gian biên dịch: scala> val x: Any = List (42) x: Any = List (42) scala> printType (x) Bất kỳ –

+0

Từ câu hỏi ban đầu của bạn, tôi nghĩ rằng bạn đặc biệt muốn có thể nhận được các tham số kiểu lúc chạy cho những thứ như 'List (42)', nơi loại args không được đưa ra một cách rõ ràng. –

+0

Tôi đã cập nhật câu trả lời của mình bằng ví dụ về trình bao bọc có thể gần hơn với những gì bạn cần. Trình bao bọc như vậy có giải quyết được vấn đề của bạn không? –

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