将 String 中的类型名称反映为 Scala 中的实际类型

2023-12-03

我有以下类对象

class DefaultValue[+A](val default: A)

object DefaultValue {

  implicit object DefaultDouble extends DefaultValue[Double](-1.0)
  implicit object DefaultFloat extends DefaultValue[Float](-1f)
  implicit object DefaultInt extends DefaultValue[Int](-1)
  implicit object DefaultBoolean extends DefaultValue[Boolean](false)

  def value[A](implicit value: DefaultValue[A]): A = value.default
}

为了使用这个我打电话DefaultValue.value[Int] or DefaultValue.value[Double] etc

但是,我需要能够调用DefaultValue.value[Int]当我有用户输入时"Int":用 String 编写的类型名,其他类似。

我希望在不进行模式匹配的情况下执行此操作,因为它本质上会破坏在函数中插入 TypeTag 的目的。 有没有更好的方法来做到这一点,也许使用 Scala Reflection?


这样做的一个问题是您将无法获得良好的返回类型。Any or DefaultValue[_]是你能得到的最好的。

您可以使用反射来编写如下内容:

import scala.reflect.runtime.{currentMirror => cm, universe => ru}

def defaultByTypename(typename: String): DefaultValue[_] = {
  val defaultValueName = "Default" + typename.trim.capitalize
  val objectSymbol = 
    ru.typeOf[DefaultValue.type].member(ru.TermName(defaultValueName))
  cm.reflectModule(objectSymbol.asModule).instance.asInstanceOf[DefaultValue[_]]
}

这将适用于implicit objects。如果你想让它与implicit vals (e.g. implicit val DefaultString = new DefaultValue[String]("~")),您必须为此情况添加代码:

def defaultByTypename(typename: String): DefaultValue[_] = {
  val defaultValueName = "Default" + typename.trim.capitalize
  val objectSymbol = 
    ru.typeOf[DefaultValue.type].member(ru.TermName(defaultValueName))
  val result = if (objectSymbol.isModule) {
    cm.reflectModule(objectSymbol.asModule).instance
  } else if (objectSymbol.isTerm) {
    cm.reflect(DefaultValue).reflectField(objectSymbol.asTerm).get
  } else sys.error("Unknown typename")
  result.asInstanceOf[DefaultValue[_]]
}

但实际上,我认为,去寻求一个并不是一个坏主意Map与对应:

val typename2DefaultValue = Map[String, DefaultValue[_]](
  "Double" -> DefaultDouble,
  "Float" -> DefaultFloat,
  "Int" -> DefaultInt,
  "Boolean" -> DefaultBoolean
)

这种方法可能更快,而且维护起来并不难。此外,可以不需要对象名称和用户输入之间的直接对应关系,或者单个字符串可以有多个可能的字符串。DefaultValue, etc.


另外,如果您将基类声明为sealed,并且仅将其扩展为objects,你可以简化这个的创建Map:

import scala.reflect.runtime.{currentMirror => cm, universe => ru}

sealed class DefaultValue[+A](val default: A)

object DefaultValue {
  implicit object DefaultDouble extends DefaultValue[Double](-1.0)
  implicit object DefaultFloat extends DefaultValue[Float](-1f)
  implicit object DefaultInt extends DefaultValue[Int](-1)
  implicit object DefaultBoolean extends DefaultValue[Boolean](false)

  val typename2DefaultValue: Map[String, DefaultValue[_]] = {
    val subclasses = ru.symbolOf[DefaultValue[_]].asClass.knownDirectSubclasses
    subclasses.map { subclass =>
      subclass.name.toString.stripPrefix("Default") ->
        cm.reflectModule(cm.staticModule(subclass.fullName)).instance.asInstanceOf[DefaultValue[_]]
    }.toMap
  }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

将 String 中的类型名称反映为 Scala 中的实际类型 的相关文章

随机推荐

  • Date.addingTimeInterval(_:) 和 Date.advanced(by:) 有什么区别?

    基金会的Datestruct 提供了两者Date addingTimeInterval and Date advanced by 它们在功能上似乎相同 但显然是不同的方法 它们之间实际上有区别还是最终相同 查看文档 advanced by
  • 使用 Tensorflow-Hub 中的 ELMo 时内存消耗大幅增加

    我目前正在尝试比较数百万个文档的相似性 对于 CPU 上的第一次测试 我将它们减少到每个字符大约 50 个 并尝试一次为其中 10 个字符获取 ELMo 嵌入 如下所示 ELMO https tfhub dev google elmo 2
  • Mockito、JUnit 和 Spring

    我今天才开始了解Mockito 我编写了一些简单的测试 使用 JUnit 见下文 但我不知道如何在 Spring 的托管 bean 中使用模拟对象 什么是最佳实践用于与 Spring 一起工作 我应该如何向我的 bean 注入模拟依赖项 你
  • 找不到 Microsoft.AspNet.SignalR.Server 3.0.0-beta7

    我在引用包时遇到问题 Microsoft AspNet SignalR Server 3 0 0 beta7 我唯一可以安装的是 测试版 5 版本 我在网上看到过其他例子 人们do引用这个 beta7 包 但我似乎找不到它 下面是我当前的
  • gdb 如何启动汇编编译的程序并一次执行一行?

    Valgrind 在他们的文档页面上说了以下内容 然后 您的程序将在 Valgrind 核心提供的合成 CPU 上运行 然而GDB似乎并没有这样做 它似乎启动了一个独立执行的单独进程 据我所知 也没有c 库 这就是我所做的 使用 clang
  • 删除sequelize返回值中的连接表数据

    我目前正在尝试删除一个joint检索关联数据时添加的表数据 查询是通过使用通过指定模型关系添加到模型的方法的sequelize来完成的 sequelize magic methods 由于某种原因 我无法做到这一点 我目前已尝试传递attr
  • Python 替换单引号(撇号除外)

    我正在对单词列表执行以下操作 我从古腾堡项目文本文件中读取行 用空格分割每一行 执行一般标点符号替换 然后在其自己的行上打印每个单词和标点符号标签 以便稍后进一步处理 我不确定如何用标签替换每个单引号或排除所有撇号 我当前的方法是使用编译的
  • SQL Server 2005:从 WHERE 子句调用存储过程

    我需要在 WHERE 子句中调用存储过程来进行 SELECT 应该是这样的 选择不同的前 10 名 i x d droit 来自 v droit d v info i WHERE d nomdroit yy AND i id2 AND 从
  • 转移矩阵

    考虑以下数据框 df data frame cusip paste A 1 10 sep xt c 1 2 3 2 3 5 2 4 5 1 xt1 c 1 4 2 1 1 4 2 2 2 5 数据分为五个州 哪个是分位数事实上 1 2 3
  • 无法读取未知加载命令0x80000022

    在我的应用程序中 我使用了大量从 Apple 的 SpeakHere 示例中复制的代码 当我在 iPhone 设备上运行该应用程序时 它在加载 XIB 之前会抛出此错误大约一百次 unable to read unknown load co
  • 如何在 Tomcat 上使用 JPA、Hibernate 和 Spring 避免类加载器泄漏

    The 打开 J2EE Web 模板是一个展示应用程序 wicket 在 Tomcat7 servlet 容器上运行的带有 Spring 和 Hibernate 的 JPA 它的 Maven 构建脚本似乎以标准方式使用组件 但是 当从 To
  • MinGW、MinGW-w64 和 MinGW-builds 之间有什么区别?

    两者有什么区别MinGW 明GW w64 and MinGW 构建 我应该使用哪一个在 Windows 8 机器上使用 Eclipse IDE 编译 c 11 源代码 MinGW 是 Windows 的 GCC 端口 并非所有 Window
  • 连续解雇2个ViewController

    我尝试了两种方法来连续解雇 2 个视图控制器 但只有其中一个被解雇 而不是第二个 method1 void LoginDone NSNotification notif self dismissViewControllerAnimated
  • 从图库中获取图像并在 ImageView 中显示

    我需要通过单击按钮从图库中获取图像并将其显示到图像视图中 我按照以下方式进行 btn image button setOnClickListener new View OnClickListener Override public void
  • 如何将文件从 DOS 转换为 Unix [关闭]

    Closed 这个问题不符合堆栈溢出指南 目前不接受答案 我需要在 PowerShell 中将文件从 DOS 转换为 Unix 我知道这在 Unix 中可以很容易地完成 dos2unix file newfile 它可以很简单 Get Co
  • 在java中在很短的时间内搜索一个非常大的ARPA文件

    我有一个将近 1 GB 的 ARPA 文件 我必须在不到 1 分钟的时间内完成搜索 我搜索了很多 但还没有找到合适的答案 我想我不必阅读整个文件 我只需跳转到文件中的特定行并读取整行 ARPA 文件的行长度不同 我不得不提一下 ARPA 文
  • 谷歌工作表单元格重新计算

    我正在创建一款棋盘游戏 并决定为此目的选择 Google 表格 我已将问题简化为由一张纸和一个脚本组成的最小示例 情况 Following points refer to my dice sheet Cells B2 C5 contain
  • 如何在不编辑函数签名的情况下纠正“无法推断适当的生命周期”?

    背景 我正在创建一个返回切片引用的迭代器 T 但数据向量需要保持不可变 迭代器cannot修改原始数据 但修改后必须重复返回相同的切片指针 我考虑过让我的迭代器拥有一个Vec
  • 使用STS创建新的Web应用程序项目时找不到Spring MVC项目?

    我是 Spring MVC 的新手 并尝试从互联网教程中学习 例如来自期刊开发 泉源 and codejava 所有这些都告诉我使用STS作为 IDE 并寻求New Project Spring Template Project Sprin
  • 将 String 中的类型名称反映为 Scala 中的实际类型

    我有以下类对象 class DefaultValue A val default A object DefaultValue implicit object DefaultDouble extends DefaultValue Double