Получение экземпляра объекта именем строки в scala

Мне нужны объект (или "одноэлементный объект" или "сопутствующий объект"... что-либо кроме класса) определенный именем строки. Другими словами, если я имею:

package myPackage
object myObject

... затем есть ли что-либо как это:

GetSingletonObjectByName("myPackage.myObject") match {
  case instance: myPackage.myObject => "instance is what I wanted"
}
26
задан Jason Plank 1 December 2011 в 13:51
поделиться

3 ответа

В Scala по-прежнему отсутствует API отражения. Вы можете получить экземпляр сопутствующего объекта, загрузив класс сопутствующего объекта:

import scala.reflect._
def companion[T](implicit man: Manifest[T]) : T = 
  man.erasure.getField("MODULE$").get(man.erasure).asInstanceOf[T]


scala> companion[List$].make(3, "s")
res0: List[Any] = List(s, s, s)

Чтобы получить нетипизированный сопутствующий объект, вы можете напрямую использовать этот класс:

import scala.reflect.Manifest
def companionObj[T](implicit man: Manifest[T]) = { 
  val c = Class.forName(man.erasure.getName + "$")
  c.getField("MODULE$").get(c)
}


scala> companionObj[List[Int]].asInstanceOf[List$].make(3, "s")
res0: List[Any] = List(s, s, s)

Это зависит от того, как scala отображается на классы java.

13
ответ дан 28 November 2019 в 06:26
поделиться

Если не считать трюков с отражением, вы не сможете. Обратите внимание, например, как метод companion определен в коллекциях Scala 2.8 - он существует для того, чтобы экземпляр класса мог получить сопутствующий объект, что в противном случае невозможно.

1
ответ дан 28 November 2019 в 06:26
поделиться

Я использовал CODECOUNT для разностных базовых линий. При этом сравниваются изменения, удаления и добавления между различными базами кода. Она предоставляется без обвинения Университетом Южной Калифорнии.

Они предоставляют только исходный код. Тем не менее, он построен чисто из застежки -молнии в cygwin с помощью g++. Они также заявляют о поддержке Visual Studio, но я не пробовал.

-121--4906670-

Отражение (взято из учебного пособия oracle java )

Отражение обычно используется программами, которые требуют возможности проверки или изменения поведения во время выполнения приложений, работающих на виртуальной машине Java. Это относительно продвинутая функция и должна использоваться только разработчиками, обладающими сильным пониманием основ языка. С учетом этого предостережения отражение является мощным методом и может позволить приложениям выполнять операции, которые в противном случае были бы невозможны.

Самоанализ (взято из archive of sun java beans tutorial )

Самоанализ - это автоматический процесс анализа узоров дизайна компонента для выявления свойств, событий и методов компонента. Этот процесс управляет публикацией и обнаружением операций и свойств компонента.

Introspection использует отражение, связь между Introspection и Reflection может рассматриваться как сходная с JavaBeans и другими классами Java.

Возможно, стоит взглянуть на «Отражение и самоанализ: объекты экспонированные» , где подробно рассматривается производительность и использование. Обратите внимание, что статья устарела, 1998 год.

Надеюсь, это поможет.

-121--1031974-

Корректировка ответа Томаса Юнга выше: лучше сказать компаньон [List.type], потому что а) это должен быть стабильный способ ссылаться на него, не зависящий от схемы искажения имени и б) вы получаете нестираемые типы.

def singleton[T](implicit man: reflect.Manifest[T]) = {
  val name = man.erasure.getName()
  assert(name endsWith "$", "Not an object: " + name)
  val clazz = java.lang.Class.forName(name)

  clazz.getField("MODULE$").get(clazz).asInstanceOf[T]
}  

scala> singleton[List.type].make(3, "a")                       
res0: List[java.lang.String] = List(a, a, a)
11
ответ дан 28 November 2019 в 06:26
поделиться
Другие вопросы по тегам:

Похожие вопросы: