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

时间:2017-02-17 07:52:57

标签: scala implicit

假设我有一组String转换器,作为Type类:

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 
}

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

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

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

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

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

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

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

1 个答案:

答案 0 :(得分:2)

如果要执行解析运行时,则需要进行反射,因为implicits是在编译时解析的。像这样的代码可以完成这项工作:

body style {display:block;color:blue;}

如果你想自动构建from itertools import chain def sort_list_ranges(input_list, low, high): sorted_list = [[] for _ in range(3)] for elem in input_list: if elem < low: sorted_list[0].append(elem) elif elem > high: sorted_list[2].append(elem) else: sorted_list[1].append(elem) print [item for sublist in sorted_list for item in sublist] 地图,你也可以使用反射,但枚举派生类需要令人惊讶的非平凡代码(包括类加载器 - 当你想到它时可以理解)。 / p>

如果你可以使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) 密封,那么在宏中枚举它的子类应该会更容易一些。

相关问题