복붙노트

[SCALA] 새로운 스칼라 반사 API와 동반자 객체의 인스턴스를 가져옵니다

SCALA

새로운 스칼라 반사 API와 동반자 객체의 인스턴스를 가져옵니다

스칼라의 새로운 반사 API로, 클래스의 동반자 개체에 대한 참조를 얻을 수 있습니다? 나는이 라인을 따라 뭔가를 생각하고있다 :

trait Base {
  def companion: MetaBase = someReflectionMagic(this).asInstanceOf[MetaBase]
}

trait MetaBase {
  // stuff
}

// ---

class Foo extends Base

object Foo extends MetaBase

assert(new Foo.companion == Foo)

해결법

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

    1.데이브! 새로운 반사에 관심을 주셔서 감사합니다. 얼리 어댑터는 상당한 정도 반사와 매크로의 개발 과정을 주도했고, 나는 우리의 놀라운 커뮤니티의 일원 것에 대해 매우 행복 해요.

    데이브! 새로운 반사에 관심을 주셔서 감사합니다. 얼리 어댑터는 상당한 정도 반사와 매크로의 개발 과정을 주도했고, 나는 우리의 놀라운 커뮤니티의 일원 것에 대해 매우 행복 해요.

    귀하의 질문에 대답하기 전에, 나는 부인으로 시작하고 싶습니다. 2.10.0-M4에서 우리는 단지 스칼라 반사 API의 기초를 마련했다. 그것은 뜨거운 언론이 아직도, 그래서 워드 프로세서는 매우 부족하며 API 정확히 편의으로 가득되지 않습니다. 그것은 작동하지만, 테스트 및 피드백이 필요합니다. 물론, 시험판 API와 장난하는 것은 곤란하지만, 내가 도울 항상 여기있어.

    https://docs.google.com/document/d/1Z1VhhNPplbUpaZPIYdc0_EUv5RiGQ2X4oqp0i-vz1qw/edit#heading=h.pqwdkl1226tc : 지금까지 우리는 미래에 반사 SIP 될 것입니다 무엇의 초안을 가지고있다. 당신은 바로 그것을 읽을 수있다, 또는 처음 내 대답은 아래를 통해 탈지 수 있습니다.

    trait Base {
      def companion: MetaBase = {
        // runtime reflection is typically done
        // by importing things from scala.reflect.runtime package
        import scala.reflect.runtime._
    
        // the new Scala reflection API is mirror based
        // mirrors constitute a hierarchy of objects
        // that closely follows the hierarchy of the things they reflect
        // for example, for a class you'll have a ClassMirror
        // for a method you'll have a MethodMirror and so on
        // why go the extra mile?
        // because this provides more flexibility than traditional approaches
        // you can read more about mirror-based designs here:
        // https://dl.dropbox.com/u/10497693/Library/Computer%20Science/Metaprogramming/Reflection/mirrors.pdf
        // https://dl.dropbox.com/u/10497693/Library/Computer%20Science/Metaprogramming/Reflection/reflecting-scala.pdf
    
        // bottom line is that to do anything you will need a mirror
        // for example, in your case, you need a ClassMirror
    
        // remember I said that mirrors provide more flexibility?
        // for one, this means that mirror-based reflection facilities
        // might have multiple implementations
        // in a paper linked above, Gilad Bracha muses over a runtime
        // that loads things remotely over the network
        // in our case we might have different mirrors for JVM and CLR
        // well, anyways
    
        // the canonical (and the only one now) implementation of the mirror API
        // is Java-based reflection that uses out of the box classloaders
        // here's its root: https://github.com/scalamacros/kepler/blob/9f71e9f114c10b52350c6c4ec757159f06e55daa/src/reflect/scala/reflect/api/Mirrors.scala#L178
        // yeah, right, I've just linked a source file from trunk
        // we'll have Scaladocs for that soon, but for now take a look
        // this file is interfaces-only and is heavy on comments
    
        // to start with Java-based reflection implementation you need a classloader
        // let's grab one and instantiate the root mirror
        // btw, the same effect could be achieved by writing
        // `scala.reflect.runtime.currentMirror`
        val rootMirror = universe.runtimeMirror(getClass.getClassLoader)
    
        // now when we've finally entered the reflective world
        // we can get the stuff done
        // first we obtain a ClassSymbol that corresponds to the current instance
        // (ClassSymbols are to Scala the same as Classes are to Java)
        var classSymbol = rootMirror.classSymbol(getClass)
    
        // having a Scala reflection entity
        // we can obtain its reflection using the rootMirror
        val classMirror = rootMirror.reflectClass(classSymbol)
    
        // now we just traverse the conceptual hierarchy of mirrors
        // that closely follows the hierarchy of Scala reflection concepts
        // for example, a ClassMirror has a companion ModuleMirror and vice versa
        val moduleMirror = classMirror.companion.get
    
        // finally, we've arrived at our destination
        moduleMirror.instance.asInstanceOf[MetaBase]
      }
    }
    
    trait MetaBase {
      // stuff
    }
    
    // ---
    
    class Foo extends Base
    
    object Foo extends MetaBase
    
    object Test extends App {
      assert(new Foo().companion == Foo)
    }
    

    최신 정보. http://dcsobral.blogspot.ch/2012/07/json-serialization-with-reflection-in.html : 다니엘 소브랄으로 우수한 게시물을 참조하시기 바랍니다.

  2. ==============================

    2.나는 유진의 마지막 코멘트를보고이 함께했다하지 않았다. 그것은 스칼라 2.10 작동합니다.

    나는 유진의 마지막 코멘트를보고이 함께했다하지 않았다. 그것은 스칼라 2.10 작동합니다.

    trait ReflectionSugars{
      import scala.reflect.runtime.{universe => ru}
      private lazy val universeMirror = ru.runtimeMirror(getClass.getClassLoader)
    
      def companionOf[T](implicit tt: ru.TypeTag[T])  = {
        val companionMirror = universeMirror.reflectModule(ru.typeOf[T].typeSymbol.companionSymbol.asModule)
        companionMirror.instance
      }
    
    }
    
    trait X extends ReflectionSugars{
       def companion = companionOf[X]
    }
    

    https://gist.github.com/piotrga/5928581

    이게 도움이 되길 바란다!

  3. from https://stackoverflow.com/questions/11020746/get-companion-object-instance-with-new-scala-reflection-api by cc-by-sa and MIT license