如何在scala中查找未引用的对象

时间:2015-01-08 22:58:44

标签: scala object lazy-initialization

我试图创建一个扩展特定类的所有对象的地图。我想在以任何其他方式使用对象之前访问此列表。我试过这段代码:

import scala.collection.mutable

abstract class Registered(tag:String) {
    Registered.registry(getClass.getName) = tag
    val x = 1
}

object Registered {
    val registry = mutable.Map[String, String]()
}

object objA extends Registered("foo")

object objB extends Registered("bar")

object TheMain {
    def main(args:Array[String]) {
        listem
        touchem
        listem
    }
    def listem = {
        println(s"listing ${Registered.registry.size} entries:")
        for ((k,v) <- Registered.registry) yield println(s"$k: $v")
    }
    def touchem = {
        val x = objA.x + objB.x
    } 
}

输出:

listing 0 entries:
listing 2 entries:
objB$: bar
objA$: foo

我需要第一行才能列出2个条目。我知道这不起作用,因为地图总是空的:对象初始化是懒惰的,所以在以某种方式引用它之前我不能引用它。

创建此类注册表的好方法是什么?可以(应该)我以某种方式使用反射吗?

2 个答案:

答案 0 :(得分:0)

这更能解释你在评论中添加的内容而不是原始问题:“在我的情况下,我想查看给定类型的所有对象,并使用具有特定标记的对象。来自命令行参数。

为什么不在这种情况下动态创建对象?像这样,也许:

class Registered(tag:String)

object Registered {
    val registry = mutable.Map[String,String]
    def apply(tag: String) = registered.getOrElseUpdate(tag, new Registered(tag))         
}

或者,你坚持使用静态创建的实例,你可以这样做(甚至不需要注册表):

sealed class Registered(tag:String) 
object objA extends Registered("foo")
object objB extends Registered("bar")
object Registered {
    def apply(tag: String) = tag match {
        case "foo" => objA
        case "bar" => objB
        case _ => throw new InvalidArgumentException("Unknown tag: %s".format(x))
    }
}

答案 1 :(得分:0)

看看Reflections library。您应该可以执行以下操作来查找从some.package.name继承的Thingy中的所有类:

def getThingies(): Set[Class[_ <: Thingy]] = {
  val reflections = new Reflections("some.package.name");
  reflections.getSubTypesOf(classOf[Thingy]);
}

当然,您可以指定classOf[Object]来获取包中的所有类。您还可以搜索具有特定注释的包。