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。你能举个例子吗?