在Scala中,如何从可序列化的类型创建TypeTag?

编程入门 行业动态 更新时间:2024-10-09 12:30:01
本文介绍了在Scala中,如何从可序列化的类型创建TypeTag?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

在Scala反射中,通常可以使用TypeCreator从Type构造TypeTag:

In Scala reflection, the TypeTag can usually be constructed from a Type using a TypeCreator:

object TypeUtils { import ScalaReflection.universe._ def createTypeTag[T]( tpe: Type, mirror: reflect.api.Mirror[reflect.runtime.universe.type] ): TypeTag[T] = { TypeTag.apply( mirror, NaiveTypeCreator(tpe) ) } case class NaiveTypeCreator(tpe: Type) extends reflect.api.TypeCreator { def apply[U <: reflect.api.Universe with Singleton]( m: reflect.api.Mirror[U]): U#Type = { // assert(m eq mirror, s"TypeTag[$tpe] defined in $mirror cannot be migrated to $m.") tpe.asInstanceOf[U#Type] } }

不幸的是,事实证明createTypeTag的输出不可序列化,这与通过编译时推断创建的typeTag不同:

Unfortunately, it turns out the output of createTypeTag is not serializable, unlike the typeTag created from compile-time inference:

import java.io.{ByteArrayOutputStream, ObjectOutputStream} import org.apache.spark.sql.catalyst.ScalaReflection import org.scalatest.FunSpec class TypeTagFromType extends FunSpec { import ScalaReflection.universe._ it("create TypeTag from reflection") { val ttg = typeTag[String] val ttg2 = TypeUtils.createTypeTag(ttg.tpe, ttg.mirror) Seq( ttg -> "from static inference", ttg2 -> "from dynamic type" ).foreach { case (tt, k) => println(k) val bos = new ByteArrayOutputStream() try { val out = new ObjectOutputStream(bos) out.writeObject(tt) out.flush() val array = bos.toByteArray } finally { bos.close() } } } }

这给出了输出:

from static inference from dynamic type scala.reflect.runtime.JavaMirrors$JavaMirror$$anon$2 java.io.NotSerializableException: scala.reflect.runtime.JavaMirrors$JavaMirror$$anon$2 at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1184) at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1548) at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1509) at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1432) at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178) at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1548) at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1509) at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1432) at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178) at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1548) at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1509) at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1432) at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178) at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1548) at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1509) at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1432) at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178) at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1548) at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1509) at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1432) at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178) at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1548) at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1509) at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1432) at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178) at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:348)

表示第二个TypeTag是不可序列化的,而第一个是不可序列化的.

Indicating that the second TypeTag is not serializable, while the first one is.

所以我的问题是:如何使第二个TypeTag像第一个一样可序列化?

So my question is: how to make the second TypeTag to be serializable like the first one?

此刻我正在使用Scala 2.12.10.

I'm using scala 2.12.10 at the moment.

推荐答案

基于如何手动创建TypeTag?

如果您需要可序列化的TypeTag并且性能不是您的主要任务 关注

if you need a serializable TypeTag and performance isn't your main concern

然后考虑

import scala.reflect.runtime.universe._ import scala.reflect.runtime.currentMirror import scala.tools.reflect.ToolBox def createTypeTag(tp: Type): TypeTag[_] = { val toolbox = universe.runtimeMirror(getClass.getClassLoader).mkToolBox() val ttree = toolbox.parse(s"scala.reflect.runtime.universe.typeTag[$tp]") toolbox.eval(ttree).asInstanceOf[TypeTag[_]] } val ttg = typeTag[List[String]] val ttg2 = createTypeTag(ttg.tpe) ...

更多推荐

在Scala中,如何从可序列化的类型创建TypeTag?

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

发布评论

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

>www.elefans.com

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