斯卡拉隐式转换无法识别
问题描述:
我有以下对象用于将对象ParsedItemDocument
转换为json
字符串。我应该注意到ParsedItemDocument
是trait
。我的问题是编译器无法识别在第二个片段中调用的隐式转换。隐式转换工作还有什么需要做的吗?斯卡拉隐式转换无法识别
import scala.language.implicitConversions
import wikidataParser.ParsedItemDocument
object Converters {
def toJson(obj: Any): String = {
val mapper = new ObjectMapper()
mapper.registerModule(DefaultScalaModule)
val out = new StringWriter
mapper.writeValue(out, obj)
return out.toString()
}
implicit def parsedItemDocumentToJsonString
(item: ParsedItemDocument): String = {
Converters.toJson(item)
}
}
现在,我使用下面的代码片段在我的代码
import tools.Converters._
import wikidataParser.ParsedItemDocument
class WikipediaRankingTester2 extends FlatSpec {
"It" should "do something" in {
val jsonrdd:RDD[String]=rankedItems.map(t:Long,ParsedItemDocument)=>
t._2.parsedItemDocumentToJsonString)//compilation error here
}
}
答
您在混合隐式转换和隐式类。
如果你想使用parsedItemDocumentToJsonString
为ParsedItemDocument
类型的对象的“方法”,那么你就需要定义隐含的
implicit class JSONParsing(item: ParsedItemDocument): String {
def parsedItemDocumentToJsonString = Converters.toJson(item)
}
如果声明它作为一个隐式转换,像你一样,那么这意味着您可以在ParsedItemDocument
类型的对象上调用String
的任何方法,因为该对象将通过隐式方法隐式转换为String
。
另外,声明整个隐式类/转换并不是很好的做法,除非您1)不能将其添加到原始类,或者2)将经常重复使用该转换,并且会节省大量的代码/可读性。这似乎并不是这种情况,因为你只是在包装Converters.toJSON
,这不是很详细,只是可读。
PS:在你的“映射”你的语法是错误的,正确的语法是
val jsonrdd = rankedItems.map(t => t._2.parsedItemDocumentToJsonString)
答
如果您隐正在这个应该这样做:
rankedItems.map(t => t._2)
您可以通过测试此请拨打外部电话
rankedItems.map(t => parsedItemDocumentToJsonString(t._2))
如果你想给ParsedItemDocument
添加一个额外的方法,你可以使用一个隐式类,我不认为你需要它,但你的代码看起来有点那样。
有在这个片段中不需要明确coversions。你的编译错误是因为你的代码在语法上是错误的(括号不平衡,t被声明为Long等),而不是隐式转换。我对你的建议是,现在忘记implicits,并专注于掌握scala语法和基本概念。 – Dima
与问题相关(对于搜索者来说这里是这个问题),但不是问题的主体:如果你的隐式转换也需要一个隐式参数......不要忘记有一个隐式值可用。 – bbarker