2014-03-04 6 views
4

문자열 값을 실제 유형으로 변환해야하므로 매크로 방식으로이 작업을 수행하기로했습니다.매크로의 하위 클래스와 일치

sealed abstract class Tag(val name: String) 
case object Case1 extends Tag("case1") 
case object Case2 extends Tag("case2") 
case object Case3 extends Tag("case3") 
etc... 

내가 간단한 해결을 작성하려는 :이 줄은 각각 Case2을 반환해야

val tag: Tag = TagResolver.fromString("case2") 

나는 데이터 유형의 무리가 있습니다. I 관리자가 수행하는 다음

def typeFromString(c: Context)(name: c.Expr[String]): c.Expr[Tag] = { 
    import c.universe._ 
    val tag = typeTag[Tag] 
    val accSymb = tag.tpe.typeSymbol.asClass 
    val subclasses = accSymb.knownDirectSubclasses // all my cases 

    subclasses.map { sub => 
     val name = sub.typeSignature.member(newTermName("name")).asMethod // name field 
     ??? 
    } 
    } 

하지만 name 필드의 값과 name: c.Expr[String] 일치 할 수있는 방법과 일치하는 경우 해당 태그를 반환?

답변

1

내가 knownDirectSubclasses 아직 컴파일되지 않은 클래스를 참조 할 수 있기 때문에이 일을 믿을 수있는 방법이 있다고 생각하지 않는다, 그래서 우리는 그들을 평가할 수 없습니다.

클래스에 주석으로이 값을 넣을 수있는 경우 클래스가 현재 컴파일 실행에서 (Symbol.annotations API를 통해) 컴파일되는 경우에도 이러한 주석을 읽을 수 있습니다. 그러나 knownDirectSubclasses에는 알려진 문제점이 있습니다 (https://issues.scala-lang.org/browse/SI-7046).

+0

실질적으로는 (예를 들어, 수행 슬릭의 사상과 같은) 물체 반대로 대소 명시 적 매핑 스트링으로 원하는 동작을 모방 할 수있다. 매우 세련된 해결책은 아니지만 일상적인 목적으로 작동합니다 : - – Ashalynd

+0

지도는 매크로로 생성 될 수 있습니다. 그 이름을 얻는 방법이 있어야합니다 :'@name ("case1") case object Case1' 또는 실행시 역 참조 할 수있는 잘 알려진 필드 이름을 통해 (예 : 매크로는'Map (Case1 -> Case1.name, ...)'을 생성 할 수 있습니다. –

관련 문제