2017-10-04 89 views
0

我想將地圖從任何值的類型轉換爲斯卡拉的字符串。轉換地圖中的值的類型 - 斯卡拉

我有這樣

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基本上從地圖[字符串,任何]轉換返回類型地圖[字符串,字符串]但我不明白爲什麼它拋出類型不匹配錯誤。

感謝

編輯-1

我想通了,我可以用name.productIterator.map(_。的toString),將其轉換爲字符串,但我想知道爲什麼我的CanBuildFrom語法是錯誤的如何。

+0

這個[Scala-lang博客](https://www.scala-lang.org/blog/2017/05/30/tribulations-canbuildfrom.html)可能會對你感興趣。實質上,Scala將在其正在進行的語言設計中使用'CanBuildFrom'。 –

回答

2

這不是CanBuildFrom的設計用途。 CanBuildFrom旨在便於實施新的集合類型。這意味着像map這樣的方法可以在特徵GenTraversableLike上定義,並且仍然能夠返回特定集合的類型,而不必像ListVector等那樣在每個子類型上覆蓋它,因爲它將CanBuildFrom構建器用於特定集合所以一般可以進行手術。

以上述方式使用CanBuildFrom將會完全混淆讀取您的代碼的任何人,它根本不是慣用的,應該避免 - 如果我看到CanBuildFrom以這種方式使用,我絕不會通過代碼審查,如果您沒有準確解釋您想要實現的目標,並以另一種方式展示瞭如何做到這一點的示例,那麼即使編譯和工作,也需要很長時間才能確定代碼的工作情況。一般來說,如果你真的知道自己在做什麼,那麼只應該使用CanBuildFrom實例,而且只有在需要提供可重用功能的實用程序庫和框架中才會使用它,它幾乎不會出現在應用程序代碼中。在我6年的Scala開發中,我從來沒有需要實現自己的CanBuildFrom,而且我只寫了兩次實際上對CanBuildFrom實例做了某些操作的代碼。

至於爲什麼你的代碼不能編譯,zip需要一個CanBuildFrom,它的第二個參數是原始集合類型的元組以及你傳入的集合的類型,也就是說,你應該提供一個CanBuildFrom[List[Any], (String, Any), List[(String, String)]]