2016-11-18 2 views
0

Hier ist, was ich habe:erweitern Liste von Werten in Fällen

sealed abstract class Codes(list: List[String]) 
object UVWCodes extends Codes(List("U", "V", "W")) 
object XYZCodes extends Codes(List("X", "Y", "Z")) 

Ich mag würde Makros verwenden, um die angegebenen Werte in erweitern:

parse(str: String): Codes = str match { 
    case "U" | "V" | "W" => UVWCodes 
    case "X" | "Y" | "Z" => XYZCodes 
} 

Da Codes ist eine versiegelte Klasse, es ist möglich, die Liste seiner Unterklassen zu erhalten. Wie kann man jedoch die Liste der Code-Literale ("U", "V" usw.) extrahieren?

Antwort

1

Wenn Sie schreiben

sealed abstract class Codes(list: List[String]) 

Liste ist nur ein Konstruktorargument die verloren ist, wenn nicht verwendet. Wenn Sie mit dem Schlüsselwort val Präfix wird es ein unveränderliches Eigentum, so dass Sie außerhalb

sealed abstract class Codes(val list: List[String]) 

UVWCodes.list // Valid code 
1

Mit entscheidenden Beiträgen von @ Edmondo1984 und Schnipseln aus anderen Ländern zugreifen können, hier ist eine vollständig codierte Lösung:

import scala.reflect.runtime.universe._ 

sealed abstract class Codes(val list: List[String]) 
object UVWCodes extends Codes(List("U", "V", "W")) 
object XYZCodes extends Codes(List("X", "Y", "Z")) 


object FindObjectsByReflection { 
    def main(args: Array[String]) = { 
    val c = typeOf[Codes].typeSymbol.asClass.knownDirectSubclasses 
    c.foreach { x => 
     val d = getObjectInstance(x.fullName).asInstanceOf[Codes] 
     println(d.list) 
    } 
    } 
    def getObjectInstance(clsName: String): AnyRef = { 
    val mirror = runtimeMirror(getClass.getClassLoader) 
    val module = mirror.staticModule(clsName) 
    mirror.reflectModule(module).instance.asInstanceOf[AnyRef] 
    } 

} 
Verwandte Themen