我正在尝试将Map的值从Any转换为Scala中的String。
我有这样的代码
import scala.collection.generic.CanBuildFrom
case class Name(FristName: String,LastName: String)
object App29 extends App {
val name = Name("mark","aden")
val stringListBuilder = new CanBuildFrom[List[Any], String, List[String]] { def apply(from: List[Any]) = this.apply(); def apply() = List.newBuilder[String] }
val result = name.getClass.getDeclaredFields.map(_.getName)
.zip(name.productIterator.toList)(stringListBuilder).toMap
}
所以我使用CanBuilderForm实质上将返回类型从Map [String,Any]转换为Map [String,String]但我不明白为什么它会抛出类型不匹配错误。
谢谢
编辑-1
我发现我可以使用name.productIterator.map(_。toString)将其转换为字符串,但我想知道为什么我的CanBuildFrom语法错误以及如何。
答案 0 :(得分:2)
那不是CanBuildFrom
的设计用途。 CanBuildFrom
旨在简化新集合类型的实现。这意味着可以在特征map
上定义GenTraversableLike
之类的方法,并且仍然能够返回特定集合的类型,而不必在每个子类型上覆盖它,如List
和{ {1}}等等,因为它使用Vector
构建器来处理特定集合,因此可以执行一般操作。
以上述方式使用CanBuildFrom
只会完全混淆读取代码的任何人,它根本不是惯用的,应该避免 - 如果我看到{我永远不会通过代码审查{1}}以这种方式使用,如果你没有准确地解释你想要实现的目标,并展示了如何以另一种方式做到这一点的例子,那么我需要花费很长时间来研究即使编译和工作,代码也在做。通常,如果您真的知道自己正在做什么,那么您应该只使用CanBuildFrom
个实例,而且只有在希望提供可重用功能的实用程序库和框架深处,它应该几乎不会出现在应用程序代码中。在我6年的Scala开发中,我从来没有一次需要实现自己的CanBuildFrom
,而且我只编写了两次实际执行CanBuildFrom
实例的代码。
至于为什么你的代码没有编译,CanBuildFrom
需要CanBuildFrom
,其第二个参数是原始集合类型的元组,以及你需要的集合的类型。 ;重新传入,即你应该提供zip
。