获取隐式证据选择的运行时类型

编程入门 行业动态 更新时间:2024-10-25 10:30:42
本文介绍了获取隐式证据选择的运行时类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

假设我有一组类型为String的String转换器:

Suppose I have a set of converters to String, as a Type class:

import scala.reflect.runtime.universe._ abstract class ToStringConverter[T] { def convert(value: T): String } implicit object IntToStringConverter extends ToStringConverter[Int] { def convert(value: Int) = value.toString } implicit object DoubleStringConverter extends ToStringConverter[Double] { def convert(value: Double) = value.toString }

以及使用类型信息选择正确的转换器的convert方法:

and a convert method that uses the type information to pick right converter:

def convert[T](v: T)(implicit ev: ToStringConverter[T]): String = ev.convert(v)

如果我事先有具体的类型,这很好用,例如:

This works fine If I have the concrete type in advance, for example:

scala> convert[Double](12.2) res0: String = 12.2 scala> convert[Int](12) res1: String = 12

是否可以将上面的convert方法与运行时类型一起使用,例如,下面的类型为't'?

Is it possible to use the convert method above with a runtime type, for example, with a type 't' below?

scala> val t = typeOf[Double] t: reflect.runtime.universe.Type = Double

推荐答案

如果要执行解析运行时,则需要进行反射,因为隐式会解决编译时的问题.像这样的代码就可以完成这项工作:

If you want to do the resolution runtime, reflection is needed, as implicits are resolved compile time. A code like this should do the job:

import scala.reflect.runtime.universe._ abstract class ToStringConverterAny { def convertAny(value: Any): String } abstract class ToStringConverter[T] extends ToStringConverterAny { def convertAny(value: Any): String = convert(value.asInstanceOf[T]) def convert(value: T): String } implicit object IntToStringConverter extends ToStringConverter[Int] { def convert(value: Int) = value.toString } implicit object DoubleStringConverter extends ToStringConverter[Double] { def convert(value: Double) = value.toString } val converters: Map[Type, ToStringConverterAny] = Map( typeOf[Int] -> IntToStringConverter, typeOf[Double] -> DoubleStringConverter ) def convert(t: Type, v: Any) = { converters(t).convertAny(v) } def convert[T](v: T)(implicit ev: ToStringConverter[T]): String = ev.convert(v) convert[Double](12.2) convert[Int](12) val t = typeOf[Double] val v: Any = 1.23 convert(t, v)

如果要自动构建converters映射,也可以为此使用反射,但是枚举派生类需要令人吃惊的非平凡代码(包括类加载器-当您考虑时可以理解).

If you want to building converters map automatically, you could also use reflection for this, but enumerating derived classes requires surprisingly non-trivial code (including class loaders - which is understandable when you think about it).

如果可以将ToStringConverterAny密封起来,则在宏中枚举其子类应该更加容易.

If you can make the ToStringConverterAny sealed, enumerating over its subclasses in a macro should be a bit easier.

更多推荐

获取隐式证据选择的运行时类型

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

发布评论

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

>www.elefans.com

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