很簡單的Spark Rdd操作,提示如下錯誤:
Error:(, ) ambiguous implicit values:
both method newIntEncoder in class SQLImplicits of type => org.apache.spark.sql.Encoder[Int]
and method newLongEncoder in class SQLImplicits of type => org.apache.spark.sql.Encoder[Long]
match expected type org.apache.spark.sql.Encoder[U]
.flatMap((line: String) => {
看錯誤堆棧,提示有多個方法滿足匿名參數,而編譯器自身無法确定需要的類型。
是以解決辦法很簡單,明确地指定flatmap函數的泛型參數即可,下面以字元串為例:
// 明确指定泛型
rdd.flatMap[String]((line: String) => {
// 傳回的資料必須是Seq,包含0到多條資料
Seq(line)
})
從上面的例子可以看出,flapMap[A]的泛型參數必須與傳回資料Seq[A]的泛型參數相同,再看一例:
rdd.flatMap[Tuple3[String, Int, String]]((line: String) => {
// 傳回類型是元組
Seq(Tuple3("yiifaa", , "well"))
})
擴充
下面的例子仿照flatmap的設計方式與調用方式。
case class Foo(baz: String)
case class Bar(baz: String)
// 測試類
case class Person[A]() {
def say(s : String): Unit = {
println(s);
}
}
// 引入泛型參數
def convert[A](s: String)(implicit reads: Person[A]): Unit = reads.say(s)
// 聲明多個隐式變量
implicit val fooReads = new Person[Foo]
implicit val barReads = new Person[Bar]
如果直接調用“convert(“Hello, yiifaa”)”方法,則提示類似的錯誤:
Error:(, ) ambiguous implicit values:
both value barReads of type Person[Bar]
and value fooReads of type Person[Foo]
match expected type Person[A]
convert("Hello, yiifaa")
Error:(, ) could not find implicit value for parameter reads: Person[A]
convert("Hello, yiifaa")
Error:(, ) not enough arguments for method convert: (implicit reads: Person[A])Unit.
Unspecified value parameter reads.
convert("Hello, yiifaa")
正确的調用方法如下:
convert[Foo]("Hello, yiifaa")
結論
使用隐式參數時,當有多個隐式對象滿足條件時,請明确指定隐式類型。