gpt4 book ai didi

scala - 使用新的 Scala 反射 API 获取伴随对象实例

转载 作者:行者123 更新时间:2023-12-03 10:13:22 25 4
gpt4 key购买 nike

使用 Scala 的新反射 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)

最佳答案

戴夫!感谢您对新反射感兴趣。早期采用者在很大程度上插入了反射和宏的开发过程,我很高兴成为我们令人惊叹的社区的一员。

在回答您的问题之前,我想先声明一下。在 2.10.0-M4 中,我们刚刚奠定了 Scala 反射 API 的基础。它仍然很火爆,所以文档非常稀缺,而且 API 并没有完全充斥着各种便利。它有效,但需要测试和反馈。当然,弄乱预发布的 API 很麻烦,但我总是在这里提供帮助。

到目前为止,我们已经有了一个将来会成为反射 SIP 的草稿:https://docs.google.com/document/d/1Z1VhhNPplbUpaZPIYdc0_EUv5RiGQ2X4oqp0i-vz1qw/edit#heading=h.pqwdkl1226tc .您可以立即阅读,也可以先浏览下面我的回答。

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)
}

更新。另请参阅 Daniel Sobral 的精彩帖子: http://dcsobral.blogspot.ch/2012/07/json-serialization-with-reflection-in.html .

关于scala - 使用新的 Scala 反射 API 获取伴随对象实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11020746/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com