복붙노트

[SCALA] 문자열에서 클래스를 생성하고 스칼라 2.10에서 인스턴스화

SCALA

문자열에서 클래스를 생성하고 스칼라 2.10에서 인스턴스화

스칼라 2.10에서 어떻게 나중에 스칼라의 반사와 인스턴스화 할 (도구 상자 API를 사용하여, 아마) 문자열에서 클래스를 생성합니까?

해결법

  1. ==============================

    1.W.r.t 컴파일 도구 상자는 컴파일 결과 결과 클래스 또는 파일 / 바이트 배열을 = 표현식을 실행 값을 반환 할 수는 없지만.

    W.r.t 컴파일 도구 상자는 컴파일 결과 결과 클래스 또는 파일 / 바이트 배열을 = 표현식을 실행 값을 반환 할 수는 없지만.

    그러나 스칼라에서 암시 적 값을 사용하여 값 수준으로 타입 수준에서 갈 너무 쉽게이기 때문에 당신이 원하는 것을 달성하기 위해 여전히 가능합니다 :

    편집하다. 2.10.0-RC1에서 도구 상자의 몇 가지 방법이 변경되었습니다. parseExpr 지금은 단지 구문 분석하고, runExpr 지금 평가라고합니다.

    scala> import scala.reflect.runtime._ // requires scala-reflect.jar
                                          // in REPL it's implicitly added 
                                          // to the classpath
                                          // but in your programs
                                          // you need to do this on your own
    import scala.reflect.runtime
    
    scala> val cm = universe.runtimeMirror(getClass.getClassLoader)
    cm @ 41d0fe80: reflect.runtime.universe.Mirror = JavaMirror with scala.tools.nsc.interpreter.IMain$TranslatingClassLoader...
    
    scala> import scala.tools.reflect.ToolBox // requires scala-compiler.jar
                                              // in REPL it's implicitly added 
                                              // to the classpath
                                              // but in your programs
                                              // you need to do this on your own
    import scala.tools.reflect.ToolBox
    
    scala> val tb = cm.mkToolBox()
    tb: scala.tools.reflect.ToolBox[reflect.runtime.universe.type] = scala.tools.reflect.ToolBoxFactory$ToolBoxImpl@3a962da5
    
    scala> tb.runExpr(tb.parseExpr("class C; scala.reflect.classTag[C].runtimeClass"))
    res2: Any = class __wrapper$1$f9d572ca0d884bca9333e251c64e980d$C$1
    

    업데이트 # 1. 당신이 java.lang.Class의 필요 및 단지 컴파일 된 클래스를 인스턴스화 할 필요가없는 경우에는 runExpr에 제출 문자열에 직접 새 C를 작성할 수 있습니다.

    업데이트 # 2. runExpr 값을 런타임에 변수 이름에서 사용자 정의 매핑을 사용하는 것도 가능하다. 예를 들면 :

    scala> val build = scala.reflect.runtime.universe.build
    build: reflect.runtime.universe.BuildApi = scala.reflect.internal.BuildUtils$BuildImpl@50d5afff
    
    scala> val x = build.setTypeSignature(build.newFreeTerm("x", 2), typeOf[Int])
    x: reflect.runtime.universe.FreeTermSymbol = free term x
    
    scala> tb.runExpr(Apply(Select(Ident(x), newTermName("$plus")), List(Literal(Constant(2)))))
    res0: Any = 4
    

    그것에 식별자를 결합 -이 예에서 I 2의 값이 무료로 용어를 생성합니다 (사용자 정의 객체가 될 수있는 값은 원시 일 필요는 없습니다). 컴파일 도구 상자에 의해 실행되는 코드에서 그대로이 값은 사용됩니다.

    이 예는 수동 AST 어셈블리를 사용하지만, 문자열을 구문 분석 언 바운드 식별자를 알게 일부 매핑에서 그 값을 보이는 함수를 작성하는 것이 가능하고 해당 무료 조건을 만듭니다. 하지만 스칼라 2.10.0에 그런 기능이 없습니다.

  2. from https://stackoverflow.com/questions/12122939/generating-a-class-from-string-and-instantiating-it-in-scala-2-10 by cc-by-sa and MIT license