我有以下代码:
import scala.reflect.runtime.{universe => ru}
case class OutputAnnotation() extends scala.annotation.StaticAnnotation
trait SimpleTrait {
var probe: Any
def outputs(): List[String] = {
val ouputs: List[String] = Nil
outputs
}
}
class WorldProbe {
@OutputAnnotation
var population: Int = 0
@OutputAnnotation
var gdp: Float = 0
var notIntersting: String = ""
}
class World extends SimpleTrait {
var probe: Any = new WorldProbe
}
object Test {
def main(args: Array[String]) {
var w: World = new World
var outp = w.outputs()
}
}
我的想法是让一些类都实现一些特性,SimpleTrait,它们应该要求它们定义一个Type ... hmm的变量探测器,这个类型不是真正的cleear,因为每个实现SimpleFeature的Class都会带有它自己的探针类型。因此,我可以在SimpleTrait中调用的唯一类型是Any。给定的代码编译,但执行会导致运行时出现堆栈溢出错误。 另外,我想从probe类中获取所有带有输出注释的变量。我怎么能这样做?
谢谢!
答案 0 :(得分:3)
您可以使用类似这样的抽象类型
来执行此操作trait Sim {
type Probe
var probe: Probe
}
class WorldProbe
class World extends Sim {
type Probe = WorldProbe
var probe: Probe = new WorldProbe
}
答案 1 :(得分:3)
您的堆栈溢出是因为您的outputs
方法。由于某种原因,编译器没有抓取变量outputs
,而是递归调用该方法。以下是具体修复:
def outputs(): List[String] = {
Nil
}
在结构方面,我更希望看到SimpleTrait有一个通用参数,如下所示:
trait SimpleTrait[T] {
var probe: T
def outputs(): List[String] = Nil
}
class World extends SimpleTrait[WorldProbe] {
var probe: WorldProbe = new WorldProbe
}
为了找到@OutputAnnotation
的所有实例,有一些事情。 1)使用Java Annotations而不是Scala Annotations(每个人都这样做)。
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface OutputAnnotation {
}
然后2)使用Jackson的Annotation Introspector轻松找到并吐出数值。
object Test {
def main(args: Array[String]): Unit = {
import scala.collection.JavaConversions._
import com.fasterxml.jackson.databind.introspect.{AnnotatedClass, JacksonAnnotationIntrospector}
val x = new WorldProbe
val introspector = new JacksonAnnotationIntrospector
val ac = AnnotatedClass.construct(x.getClass, introspector, null)
val outFields = ac.fields().filter(_.hasAnnotation(classOf[OutputAnnotation]))
for (field <- outFields) {
field.fixAccess()
println(field.getName + " => " + field.getValue(x))
}
}
}
产生此输出:
population => 0
gdp => 0.0