[英]How is a typed Scala object losing its type?
In the following piece of code, entities
is a Map[String, Seq[String]]
object that I receive from some other piece of code.在下面的一段代码中, entities
是一个Map[String, Seq[String]]
对象,它是我从其他一些代码中收到的。 The goal is to map the entities object into a two column Spark DataFrame;目标是将实体对象映射到一个两列的 Spark DataFrame 中; but, before I get there, I found some very unusual results.但是,在我到达那里之前,我发现了一些非常不寻常的结果。
val data: Map[String, Seq[String]] = Map("idtag" -> Seq("things", "associated", "with", "id"))
println(data)
println(data.toSeq)
data.toSeq.foreach{println}
data.toSeq.map{case(id: String, names: Seq[String]) => names}.foreach{println}
val eSeq: Seq[(String, Seq[String])] = entities.toSeq
println(eSeq.head)
println(eSeq.head.getClass)
println(eSeq.head._1.getClass)
println(eSeq.head._2.getClass)
eSeq.map{case(id: String, names: Seq[String]) => names}.foreach{println}
The output of the above on the console is:上面在控制台上的输出是:
Map(idtag -> List(things, associated, with, id))
ArrayBuffer((idtag,List(things, associated, with, id)))
(idtag,List(things, associated, with, id))
List(things, associated, with, id)
(0CY4NZ-E,["MEC", "Marriott-MEC", "Media IQ - Kimberly Clark c/o Mindshare", "Mindshare", "WPP", "WPP Plc", "Wavemaker Global", "Wavemaker Global Ltd"])
class scala.Tuple2
class java.lang.String
class java.lang.String
Exception in thread "main" java.lang.ClassCastException: java.lang.String cannot be cast to scala.collection.Seq
at package.EntityList$$anonfun$toStorage$4.apply(EntityList.scala:31)
The data
object that I hardcoded acts as expected.我硬编码的data
对象按预期运行。 The .toSeq
function on the entities map produces a Seq
(implemented as an ArrayBuffer) of tuples;实体映射上的.toSeq
函数生成元组的Seq
(实现为 ArrayBuffer); and these tuples can be processed through mapping.这些元组可以通过映射进行处理。
But using the entities
object, you can see that when I take the first element using .head
and it is a Tuple2[String, String]
.但是使用entities
对象,您可以看到当我使用.head
获取第一个元素时,它是一个Tuple2[String, String]
。 How can that possibly happen?这怎么可能发生? How does the second element of the tuple turn into a String and cause the exception?元组的第二个元素如何变成字符串并导致异常?
Further confusing me, if the last line is changed to reflect the Tuple2[String, String]
: Tuple2[String, String]
我困惑的是,如果最后一行更改为反映Tuple2[String, String]
:
eSeq.map{case(id: String, names: String) => names}.foreach{println}
then we get a compile error:然后我们得到一个编译错误:
/path/to/repo/src/main/scala/package/EntityList.scala:31: error: pattern type is incompatible with expected type;
found : String
required: Seq[String]
eSeq.map{case(id: String, names: String) => names}.foreach{println}
I can't replicate this odd behavior with a Map[String, Seq[String]]
that I create myself, as you can see in this code.我无法使用我自己创建的Map[String, Seq[String]]
复制这种奇怪的行为,正如您在此代码中所见。 Can anyone explain this behavior and why it happens?谁能解释这种行为以及为什么会发生?
The problem appears to be that entities.toSeq
is lying about the type of the data that it is returning, so I would look at "some other piece of code" and check it is doing the right thing.这个问题似乎是entities.toSeq
说谎关于数据的类型,它是返回,所以我想看看“的一些其他的代码”,并检查它是做正确的事。
Specifically, it claims to return Seq[(String, Seq[String])]
and the compiler believes it.具体来说,它声称返回Seq[(String, Seq[String])]
并且编译器相信它。 But getClass
shows that the second object in the tuple is actually java.lang.String
not Seq[String]
.但是getClass
显示元组中的第二个对象实际上是java.lang.String
而不是Seq[String]
。
If this were correct then the match
statement would be using unapply
to extract the value and then getting an error when it tried to convert names
to the stated type.如果这是正确的,那么match
语句将使用unapply
来提取值,然后在尝试将names
转换为指定的类型时出错。
I note that the string appears to be a list of strings enclosed in [
]
, so it seems possible that whatever is creating entities
is failing to parse this into a Seq
but claiming that it has succeeded.我注意到该字符串似乎是一个包含在[
]
中的字符串列表,因此似乎有可能创建entities
任何内容都未能将其解析为Seq
但声称它已成功。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.