2013-06-07 35 views
15

Tôi đang xem xét API phản ánh scala và tôi nhận được rất nhiều ngoại lệ.Scala - No TypeTag Có ngoại lệ khi sử dụng lớp vỏ để cố gắng lấy TypeTag?

Doc tham khảo: http://docs.scala-lang.org/overviews/reflection/environment-universes-mirrors.html

Làm thế nào để tôi có được typetag từ chung chung?

def getChildSettings[T: ru.TypeTag](path: String, settingsParameterObject: T) = { 

    import scala.reflect.runtime.{ currentMirror => m } 

    val m = ru.runtimeMirror(getClass.getClassLoader) 
    val classC = ru.typeOf[T].typeSymbol.asClass 
} 

tôi nhận được một ngoại lệ:

No TypeTag available for ParameterObject.type 

Thậm chí một ví dụ rất đơn giản dường như không làm việc (chỉnh sửa có nó trong repl)

import scala.reflect.runtime.universe._ 
import scala.reflect.runtime.currentMirror 
import scala.reflect.runtime.{universe => ru} 

def getTypeTag[T: ru.TypeTag](obj: T) = ru.typeTag[T] 

case class ParameterObject(stringType: String, optionType: Option[String]) 

getTypeTag(ParameterObject) 

Tôi đoán đó là một cái gì đó về cách tôi gọi phương thức.

+1

Hum, chỉ cần dán ví dụ đơn giản của bạn trong REPL (và xóa 'settings.') làm việc cho tôi trên 2.10.1. Bạn có thể bỏ lỡ scala-phản ánh trên classpath của bạn? – gourlaysama

+0

Đam tàn! Bạn nói đúng nó làm việc trong repl. Tôi đã tìm ra - các lớp vỏ không thể lồng nhau !! Tôi đã có trường hợp lớp được xác định bên trong một trường hợp thử nghiệm và đó là những gì đã gây ra vấn đề. – JasonG

Trả lời

31

Cuối cùng tôi đã tìm ra vấn đề là gì. Các lớp chữ hoa phải được xác định ở mức cao nhất - chúng không thể lồng nhau. Một cái gì đó như thế này sẽ thất bại.

class Foo { 
    describe("getSettings") { 
    case class ParameterObject(foo: String) 
    settings.getTypeTag(path, ParameterObject) 
    } 
} 

class Clazzy { 
     def getTypeTag[T: TypeTag](obj: T) = ru.typeTag[T] 
} 
+0

Mọi người đọc bài này, xem thêm câu trả lời của Yaroslav. Bạn có thể _either_ di chuyển tất cả các lớp của bạn lên cấp cao nhất và tiếp tục sử dụng 'typeOf' /' TypeTag' _or_ giữ chúng ở vị trí của chúng và sử dụng 'weakTypeOf' /' WeakTypeTag' để thay thế. (Trong trường hợp cả hai chức năng hoạt động, chúng tạo ra cùng một đầu ra.) –

+0

Điều này có nghĩa là chúng ta không thể viết một kịch bản lệnh scala đơn giản như trong bài viết gốc của bạn và làm cho nó chạy? – Xiangyu

3

Bạn cần một TypeTag tại thời gian biên dịch, bởi vì đó là cách để làm việc xung quanh tẩy xoá:

import scala.reflect.runtime.{currentMirror => m, universe => ru} 

def getChildSettings[T: TypeTag](path: String, settingsParameterObject: T) = { 
    val tpe = ru.typeOf[T] 
    // val classC = tpe.typeSymbol.asClass 
    val ctor = tpe.declaration(ru.nme.CONSTRUCTOR).asMethod 
    ... 
} 

Các Scala Documentation Overview for Reflection đưa ra một ví dụ về nhận và gọi một constructor.

+0

Ah được rồi. Tôi hiểu rồi. Tôi phải đi [T: ru.TypeTag] thực sự - cảm ơn người đàn ông - Tôi không thể nhìn thấy những gì tôi đã mất tích. – JasonG

+0

Thiệt hại vẫn cung cấp thẻ loại lỗi không khả dụng. – JasonG

+0

Tôi nghĩ đó là cách tôi gọi methdod. – JasonG

8

Nếu bạn cần thẻ loại cho các lớp lồng nhau, bạn có thể sử dụng WeakTypeTag. Tôi không biết tại sao, nhưng that's intentionally.

4

Vui lòng khai báo lớp Trường hợp trước khi bạn chạy lớp học chính

Ví dụ

case class Person(name: String, age: Long) 

def main(args: Array[String]) { 
    ... 
    val people = sc.textFile("C:\\winutils\\people.txt").map(_.split(",")).map(p => Person(p(0), p(1).trim.toInt)).toDF() 
3

Thêm mã này trong pom.xml của bạn

<dependency> 
    <groupId>org.scala-lang</groupId> 
    <artifactId>scala-reflect</artifactId> 
    <version>2.12.0-M4</version> 
</dependency> 
+0

Cảm ơn rất nhiều! Nhận xét này ở phần cuối của một chủ đề - là những gì làm việc cho tôi! – user1571307

+0

Yup, cũng đã giúp tôi trong bối cảnh của Apache Spark. –

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