简体   繁体   English

类型化 Scala 对象如何丢失其类型?

[英]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.

相关问题 Scala:如何编写返回 object 类型为接收器的实现类型的方法 - Scala: how to write method that returns object typed to implementation type of receiver Scala:返回所提供类型的对象的类型化方法 - Scala: Typed method that returns object of the provided Type 如何通过使用 Scala 中的类型在特征中使用 Object - How to use an Object in a trait by using its type in Scala Scala协方差丢失类型约束 - Scala covariance losing type constraints 如何将Scala中的对象强制转换为其自身类型和任何不相关特征的交集? - How can an object in Scala be cast to the intersection of its own type and any unrelated trait? Scala反思:如何在给定“字符串类型”类名和方法名的情况下构造对象并运行其方法? - Scala reflection: How to construct object and run its methods given 'String-type' class name and method name? Scala:如何实现一个包含scala“typed”类而没有类型参数的java接口 - Scala: how to implement a java interface that contains scala “typed” classes without their type parameters 如何在Scala中将String类型转换为Object类型 - How to transfer String type to Object type in Scala Scala默认类型列表为String类型 - Scala defaulting typed list to be of type String 此类型参数如何“键入”? - How is this type parameter 'typed'?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM