Json 区分映射[字符串,字符串]和映射[字符串,对象]

Json 区分映射[字符串,字符串]和映射[字符串,对象],json,scala,jackson,Json,Scala,Jackson,我在项目中创建了两个不同的地图。我对这两者都使用了类型别名 type alias1 = Map[String, ScalaObject] type alias2 = Map[String, String] 我有一个匹配案例,我想区分这两种情况,因为两种情况都需要进行不同的操作 val obj:T=fromJson[T](jacksonMapper,json) 如何区分这两种情况?ADT将创建一个封闭的特征,每个案例都有一些案例类别;因此,一个用于映射[String,String],另一个用于映

我在项目中创建了两个不同的地图。我对这两者都使用了类型别名

type alias1 = Map[String, ScalaObject]
type alias2 = Map[String, String]
我有一个匹配案例,我想区分这两种情况,因为两种情况都需要进行不同的操作

val obj:T=fromJson[T](jacksonMapper,json)


如何区分这两种情况?

ADT将创建一个封闭的特征,每个案例都有一些案例类别;因此,一个用于映射[String,String],另一个用于映射[String,ScalaObject],您可以在case类上进行模式匹配。
所以像这样:

sealed trait MyType extends Product with Serializable
final case class ObjMap(data: Map[String, ScalaObject]) extends MyType
final case class StrMap(data: Map[String, String]) extends MyType

val obj: MyType = ???
obj match {
  case ObjMap(_) => operation1()
  case StrMap(_) => operation2()
}

类型类方法可能太复杂了。

要理解为什么在运行时无法区分这两个映射,有两个关键概念:

  • 类型擦除,其中编译时参数seed type
    Map[String,String]
    成为运行时类
    Map
  • 模式匹配转换为运行时
    isInstanceOf
    asInstanceOf
    调用
考虑下面的简化示例

case class Foo[T](i: T) 

val fooInt = Foo[Int](42)
val fooStr = Foo[String]("")

fooInt.isInstanceOf[Foo[String]]
// val res0: Boolean = true
请注意,
isInstanceOf
如何在运行时无法检查编译时类型参数
T
,因此无法区分
fooInt
fooStr
。实际上,我们能做的最好的事情是

fooInt.isInstanceOf[Foo[_]]
if (fooInt.isInstanceOf[Foo[String]]) "oops :("
其中下划线
\uu
用于传达类型擦除的事实

接下来考虑下面的模式如何匹配

(fooInt: Any) match { case str: Foo[String] => "oops :(" }
// val res1: String = oops :(
实际上变成了

fooInt.isInstanceOf[Foo[_]]
if (fooInt.isInstanceOf[Foo[String]]) "oops :("
由于类型擦除,其计算结果同样错误地为“oops:(“”


另一种方法是,在丢弃类型参数之前,尽量在编译时执行。类型类可以被认为是在类型擦除之前发生的一种编译时模式匹配。

由于类型擦除,两种类型在运行时成为同一个类(在运行时执行模式匹配)你可以使用简单的ADT或typeclass。你能举个例子吗?