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

编程入门 行业动态 更新时间:2024-10-28 18:34:14
本文介绍了将 String 中的类型名称反映为 Scala 中的实际类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我有以下类对象

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] 或 DefaultValue.value[Double] 等

To use this I call DefaultValue.value[Int] or DefaultValue.value[Double] etc

但是,当我将用户输入为 "Int" 时,我需要能够调用 DefaultValue.value[Int] :用字符串编写的类型名,类似地其他.

However, I need the ability to call DefaultValue.value[Int] when I have user input as "Int" : the typename written in String, and similarly for others.

我希望在没有模式匹配的情况下执行此操作,因为它本质上会超过在函数中插入 TypeTag 的目的.有没有更好的方法可以做到这一点,也许使用 Scala 反射?

I wish to do this without pattern-matching, as it would essentially beat the purpose of inserting TypeTag in the function. Is there a better way to do this, perhaps using Scala Reflection?

推荐答案

这样做的一个问题是您将无法获得好的返回类型.Any 或 DefaultValue[_] 是最好的.

One problem with that is that you won't be able to get a good return type. Any or DefaultValue[_] is the best you can get.

你可以使用反射来写这样的东西:

You can use reflection to write something like this:

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 vals 一起使用(例如 implicit val DefaultString = new DefaultValue[String]("~")),则必须为这种情况:

This will work for implicit objects. If you want it to work with implicit vals (e.g. implicit val DefaultString = new DefaultValue[String]("~")), you'd have to add code for this case:

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 等提供多个可能的字符串.

This approach is probably faster and really not that hard to maintain. Also, it would be possible to not require direct correspondence between object name and user input, or to have several possible strings for a single DefaultValue, etc.

此外,如果您将基类声明为 sealed,并且仅使用 objects 对其进行扩展,则可以简化此 Map:

Also, if you declare the base class as sealed, and extend it only with objects, you could streamline the creation of this 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 } }

更多推荐

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

本文发布于:2023-11-25 05:06:25,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1628449.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:类型   名称   String   Scala

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!