Spark:flatmap函数提示“ambiguous implicit values”的解决办法

很简单的Spark Rdd操作,提示如下错误:

Error:(46, 15) 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", 30, "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:(24, 12) 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:(24, 12) could not find implicit value for parameter reads: Person[A]
    convert("Hello, yiifaa")
Error:(24, 12) not enough arguments for method convert: (implicit reads: Person[A])Unit.
Unspecified value parameter reads.
    convert("Hello, yiifaa")

正确的调用方法如下:

convert[Foo]("Hello, yiifaa")

结论

使用隐式参数时,当有多个隐式对象满足条件时,请明确指定隐式类型。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值