2012-11-01 26 views
8

我們可以得到val s: String使用反射從功能f外的類型?結構亞型反射

val f = (r: {val s: String}) => { 
} 
+0

在2.9或2.10還是不重要? –

+0

2.9或2.10並不重要。但我通常使用2.9.2。 – sndyuk

+1

我非常懷疑在沒有使用編譯器的情況下它可能在2.9中。在2.10中有反射api,可能會允許檢查「r」的類型。 – pedrofurla

回答

10
scala> import scala.reflect.runtime.{universe => ru} 
import scala.reflect.runtime.{universe=>ru} 

scala> import scala.reflect.runtime.universe._ 
import scala.reflect.runtime.universe._ 

scala> def typeOf[T: ru.TypeTag](x: T) = ru.typeOf[T] // capture compile-time type info 
typeOf: [T](x: T)(implicit evidence$1: reflect.runtime.universe.TypeTag[T])reflect.runtime.universe.Type 

scala> val f = (r: {val s: String}) => {} 
f: AnyRef{val s: String} => Unit = <function1> 

scala> val tpe = typeOf(f) 
tpe: reflect.runtime.universe.Type = scala.AnyRef{val s: String} => Unit 

scala> ru.showRaw(tpe) 
res0: String = TypeRef(ThisType(scala), scala.Function1, List(RefinedType(List(TypeRef(ThisType(scala), newTypeName("AnyRef"), List())), Scope(newTermName("s"))), TypeRef(ThisType(scala), scala.Unit, List()))) 

scala> val ru.TypeRef(_, _, refinement :: _) = tpe 
refinement: reflect.runtime.universe.Type = scala.AnyRef{val s: String} 

使用Scala反射一個也可以生成用於結構類型嘲笑如下:https://gist.github.com/4008389。鏈接的要點使用工具箱和運行時反射來完成,但是這種情況也適用於宏。

+0

您使用哪個版本的Scala?我在最後一個語句中得到一個警告:'警告:抽象類型模式reflect.runtime.universe.TypeRef未被選中,因爲它被擦除消除了' – sschaef

+1

導入是必需的。它將TypeRef的類標記帶入作用域,從而消除未經檢查的警告。 –

+0

有沒有什麼辦法可以創建優化的實例? – sndyuk