完美处理动态实例化中的scala构造函数

2024-03-25

我已经整理了这个工作代码,可以从给定的动态实例化一个类name: String(以下)。这适用于简单的情况 - 类和具有一个构造函数的案例类。

我不确定如何处理存在多个构造函数的一般情况。我认为它们只能通过它们的签名来区分,但发现伴生对象、类和案例类之间的概念交互有点难以推理。需要考虑的所有“构建”场景的完整描述是什么,或者,您将如何将其发展为完全通用?

这段代码在遍历伴生对象时令人尴尬地失败,这证明了它的不灵活性。

如果有人愿意加入这个思维练习,希望这段代码能够提供方便的测试和修补流程。

import scala.reflect.runtime.universe

case class CaseClass(foo: Int) {
  println(s"${getClass.getSimpleName} Instantiated with $foo")
}

class BaseClass(foo: Int) {
  println(s"${getClass.getSimpleName} Instantiated with $foo")
}

object BaseClass { 
  def apply(foo:Int) = {
    println(s"going through companion object ${getClass.getSimpleName}")
    new BaseClass(foo+10) }
  }

class GenericClass[T](foo: T) {
  println(s"${getClass.getSimpleName} Instantiated with $foo")
}

object Inst {

  private def log(s: String) = println(Console.YELLOW + Console.BOLD + s + Console.RESET)

  private def selectConstructor(symbol: universe.Symbol) = {
    val constructors = symbol.typeSignature.members.filter(_.isConstructor).toList
    if (constructors.length > 1) log(
           s"""Warning: $symbol has several constructors, arbitrarily picking the first one: 
              |         ${constructors.mkString("\n         ")}""".stripMargin)
    constructors.head.asMethod
  }

  def apply(className: String, arg: Any) = {
    val runtimeMirror: universe.Mirror = universe.runtimeMirror(getClass.getClassLoader)

    val classSymbol: universe.ClassSymbol = runtimeMirror.classSymbol(Class.forName(className))

    val classMirror: universe.ClassMirror = runtimeMirror.reflectClass(classSymbol)

    if (classSymbol.companion.toString() == "<none>") // TODO: use nicer method "hiding" in the api?
    {
      log(s"Info: $className has no companion object")
      val constructorMirror = classMirror.reflectConstructor(selectConstructor(classSymbol)) // we can reuse it
      constructorMirror(arg)
    }
    else
    {
      val companionSymbol = classSymbol.companion
      log(s"Info: $className has companion object $companionSymbol")
      val constructorMirror = classMirror.reflectConstructor(selectConstructor(classSymbol)) // we can reuse it
      constructorMirror(arg)
    }   
  }
}

object Test extends App {
  val c1 = Inst("BaseClass", 3)
  val c2 = Inst("BaseClass", 4)
  val cc = Inst("CaseClass", 5)
  val gc1 = Inst("GenericClass", "I am generic")
  val gc2 = Inst("GenericClass", gc1)
  println(s"""\nthese objects have been instantiated:\n${List(c1,c2,cc,gc1,gc2).mkString("\n")}""")
}

请注意,它需要这个build.sbt或类似的:

lazy val reflection = (project in file("."))
  .settings(
    scalaVersion := "2.11.7",
    libraryDependencies ++= Seq(
      "org.scala-lang" % "scala-compiler" % scalaVersion.value % "provided",
      "org.scala-lang" % "scala-library" % scalaVersion.value % "provided"
    )
  )

None

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

完美处理动态实例化中的scala构造函数 的相关文章

随机推荐

  • 下载并解压内存中的 gzip 文件?

    我想使用 urllib 下载文件并在保存之前将文件解压缩到内存中 这就是我现在所拥有的 response urllib2 urlopen baseURL filename compressedFile StringIO StringIO c
  • 将会话从模板视图传递到 python 请求 api 调用

    我想使用请求库从 Django TemplateView 进行多个内部 REST API 调用 现在我也想将会话从模板视图传递到 api 调用 考虑到性能 推荐的方法是什么 现在我正在提取cookie从目前的request模板视图中的对象
  • 将 C 字节数组转换为 long long

    我的应用程序中有一个 8 字节数组 其中包含以下数据 00000133339e36a2 该数据代表一个长整型 在写入数据的平台上 在 Mac 上这将是一个长整型 其值为 1319420966562 在实际应用中 这是一组半随机的数据 因此数
  • D3 弧形端部 V 形

    我画了一个arc https github com d3 d3 shape arcs使用 D3 js 默认情况下具有方形末端 var arc d3 arc innerRadius 0 outerRadius 100 startAngle 0
  • 文件包含路径分隔符。

    当我尝试检查特定文件是否存在时 我得到java lang illegalArgumentException File contains a path separator 使用 getFileStreamPath 执行此操作的正确方法是什么
  • Laravel 按字段长度排序

    我想构建一个按特定字段长度对数据进行排序的查询 我需要将此查询重写为 laravel 的 Eloquent ORM SELECT FROM table ORDER BY CHAR LENGTH field 看起来orderByRaw这就是您
  • 有人有使用 OpenCV 和 python 进行描述符提取的示例吗?

    我正在尝试使用 OpenCV 从图像中提取 SURF 描述符 我正在使用 OpenCV 2 4 和 Python 2 7 但很难找到任何提供有关如何使用这些函数的信息的文档 我已经能够使用以下代码来提取特征 但我找不到任何明智的方法来提取描
  • Struts 2下载-如何动态配置文件名?

    我正在开发一个应用程序 人们可以将所需的文件从数据库中提到的位置下载到本地 我正在使用 struts 2 从服务器下载文件 我可以毫无例外地下载该文件 并且运行完美 但是下载的文件具有我在 struts xml 中指定的文件名 我希望它是正
  • `ifstream::readsome` 何时设置 `eofbit`?

    这段代码永远循环 include
  • 如何将 API 参数传递给 GCP 云构建触发器

    我有一大组 GCP Cloud Build 触发器 通过云调度程序调用 所有触发器都运行良好 现在 我想通过外部 API 调用来调用这些触发器 并向它们传递参数值和数量不同的动态参数 我能够通过运行 API 请求来启动触发器 但我发送的 A
  • Spring 3.0 使用 Jackson 消息转换器进行 JSON 响应

    我将我的消息转换器配置为杰克逊的消息转换器 class Foo int x int y 并在控制器中 ResponseBody public Foo method return new Foo 3 4 由此 我期望从服务器返回一个 JSON
  • 如何通过CloudFormation设置EC2实例根卷的标签

    使用 CloudFormation 创建 EC2 实例 但根卷的名称 标签 为空 如何使用CloudFormation进行设置 ec2 instance yml CloudFormation template MyInstance Type
  • 连接到 Tomcat 上的套接字?

    我正在尝试从独立小程序连接到在 tomcat 上运行的 servlet Servlet public void init ServletConfig config throws ServletException super init con
  • Application Insights - 仅获取客户端数据,不获取服务器数据。

    我有一个托管在 Windows Server 2008 上的 ASP Net MVC 4 应用程序 我正在使用 Microsoft Application Insights 它非常适合客户端指标 例如客户端处理时间 自定义事件 用户 会话
  • tbb:concurrent_hash_map:英特尔线程构建模块 (TBB) 的示例代码

    寻找要使用的示例代码tbb concurrent hash map
  • 使用 C# 9 顶级语句时,如何在 Main 范围之外添加代码?

    我的理解是类似直接写代码到老的 static void Main string args 无需显示上面的内容 但是 我曾经在类 Program 中声明我的变量 以便从其他类访问它们 抱歉 如果不是最佳实践 我自己学习了 C 只要它有效 我对
  • 强制卸载 Visual Studio

    卸载 Microsoft Visual Studio Ultimate 2015 Preview 时 它会抛出错误并引用 Microsoft Visual Studio Ultimate 2015 Preview 已停止工作 留言内容包括
  • 如何在运行时更改相机的预览?

    我正在尝试创建一个应用程序 它可以从相机视图中捕获一些 x y 大小的矩形部分 为了实现这一目标 我已经使用了许多线程 但似乎没有一个线程能够按要求工作 基本上我想要实现的目标如下所示 我的要求是 当我打开相机时 屏幕上应该有一个矩形突出显
  • 访问最终类的 @NSManaged 属性时出现 Swift 链接器错误

    我在一个较大的项目中遇到了问题 并将其归结为这个简单的代码 出于演示目的 我创建了一个新的 Swift 项目 在 Model swift 文件中包含以下内容 import Foundation import CoreData class A
  • 完美处理动态实例化中的scala构造函数

    我已经整理了这个工作代码 可以从给定的动态实例化一个类name String 以下 这适用于简单的情况 类和具有一个构造函数的案例类 我不确定如何处理存在多个构造函数的一般情况 我认为它们只能通过它们的签名来区分 但发现伴生对象 类和案例类