2014-11-06 76 views
1

我有以下代碼:階:定義一個特徵類型的任何一個變量

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的探針,類型不是真的,因爲實現SimpleFeature的每個類都將帶有它自己的探針類型。因此,我可以在SimpleTrait中進行探測的唯一類型是Any。給定的代碼編譯,但在運行時執行導致stackoverflow錯誤。 在附註上,我想從probe類中獲取所有使用輸出註釋註釋的變量。我怎麼能這樣做?

謝謝!

+1

堆棧溢出是僅僅是因爲你拼錯了'VAL ouputs'(而不是'outputs'),這使得第二線實際調用相同的方法遞歸地廣告vitam aeternam。 – sjrd 2014-11-06 21:29:51

回答

3

你可以用一個抽象的類型是這樣的

trait Sim { 
    type Probe 
    var probe: Probe 
} 

class WorldProbe 

class World extends Sim { 
    type Probe = WorldProbe 
    var probe: Probe = new WorldProbe 
} 
+0

謝謝,這工作:) – 2014-11-06 13:50:47

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)使用傑克遜的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 
相關問題