当前位置:   article > 正文

could not find implicit value for evidence parameter of type 怎么解决?—— Flink TypeInformation_error:(48, 59) could not find implicit value for e

error:(48, 59) could not find implicit value for evidence parameter of type

参考:

Flink docs

Flink 源码

Error:(.., ..) could not find implicit value for evidence parameter of type
...
  • 1
  • 2

首先,这句错误信息代表的含义是:Scala无法找到隐式转换的参数,也就是他说的evidence parameter。在Flink Scala API中,通常有两种情况会造成这类报错。

1. Flink运行环境缺少TypeInformation

第一种非常简单,属于上手Flink第一课的内容,获取运行环境StreamExecutionEnvironment.getExecutionEnvironment

import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment //如果是这么引用运行环境,大概率会报错
object TestTypeInformation {
  def main(args: Array[String]): Unit = {
    val env = StreamExecutionEnvironment.getExecutionEnvironment
    val dataStream: DataStream[(String, Long)] = env.fromCollection(Seq(("A", 1L))) //这里就会报错了
    //...
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

错误信息如下:

Error:(9, 68) could not find implicit value for evidence parameter of type org.apache.flink.api.common.typeinfo.TypeInformation[(String, Long)]
    val dataStream: DataStream[(String, Long)] = env.fromCollection(source)
  • 1
  • 2

造成他的问题就是上面所说,我们需要一个TypeInformation[(String, Long)],但是我们没有提供,也找不到任何的隐式值。所有创建流的API都需要这样的TypeInformation,不仅如此,Flink中的泛型T都需要被包装成TypeInformation[T]。Flink通过TypeInformation中的信息,来决定如何高效的序列化和反序列化这个泛型的对象。因为写泛型的人并不知道最终泛型会是那个类,所以我们需要另外去提供这个泛型所匹配的类的信息。

官方直接给出了解决方法:把StreamExecutionEnvironment所在的整个包引入。也就是把:

import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment
  • 1

换成

import org.apache.flink.streaming.api.scala._
  • 1

官方的说法是产生TypeInformation的代码没有被引入。那这个代码到底在哪里?

实际上创建我们要找的代码在包对象中。也就是org.apache.flink.streaming.api包下面的package.scala。第一行代码就是了。这是一个隐式转换函数,输出就是一个TypeInformation。就是这个函数为我们提供了之前缺少的TypeInformation。Flink利用这个scala的macro,让代码在被编译的时候,就能够获得所有的参数和返回值是什么类型,然后包装进TypeInformation。

package object scala {
  
  // We have this here so that we always have generated TypeInformationS when
  // using the Scala API
  implicit def createTypeInformation[T]: TypeInformation[T] = macro TypeUtils.createTypeInfo[T]
//...
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

我们只用引入这个函数,就不会再出现这种错误了,不需要引入整个包。

import org.apache.flink.streaming.api.scala.{createTypeInformation, StreamExecutionEnvironment}
object TestTypeInformation {
  def main(args: Array[String]): Unit = {
    val env = StreamExecutionEnvironment.getExecutionEnvironment
    val dataStream: DataStream[(String, Long)] = env.fromCollection(Seq(("A", 1L))) //这里不再会报错
    //...
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

那为什么要引入整个包?我个人猜测是为了方便记,不需要记忆具体是那个方法,而且这个包内的API很常用,之后不需要再引入包中其他的类。

除了这个最基本的情况会报这个错误,另外一种情况是:我们自己定义的泛型被传入了flink中需要TypeInformation的泛型的地方

2. 自定义泛型没有声明为TypeInformation

假如我们自己定义了一个带泛型的方法,它所做的就是调用map方法,把每个tuple2中的第一个元素取出。map的API的泛型规定了它的输出是一个TypeInformation。

  def map[R: TypeInformation](fun: T => R): DataStream[R] = {
  • 1

而我们自己定义的泛型并没有规定输出他是一个TypeInformation。

import org.apache.flink.api.common.typeinfo.TypeInformation
import org.apache.flink.streaming.api.scala._
object TestTypeInformation {
  def selectFirst[T](input: DataStream[(T, T)]): DataStream[T] = {
    input.map(_._1)
  }
  def main(args: Array[String]): Unit = {
    val env = StreamExecutionEnvironment.getExecutionEnvironment
    val dataStream = env.fromCollection(Seq((1L, 3L), (2L, 4L)))
    val result = selectFirst(dataStream)
    result.print()
    env.execute()
  }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

错误信息就产生于map函数:

Error:(7, 14) could not find implicit value for evidence parameter of type org.apache.flink.api.common.typeinfo.TypeInformation[T]
    input.map(_._1)
  • 1
  • 2

意思跟第一种情况类似,就是map需要输出TypeInformation,但是我们找不到。这时我们只需要将我们自己的泛型限制为TypeInformation,就能够触发隐式转换了。

import org.apache.flink.api.common.typeinfo.TypeInformation
def selectFirst[T: TypeInformation](input: DataStream[(T, Long)]): DataStream[T] = { 
  input.map(_._1)
}
  • 1
  • 2
  • 3
  • 4
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/500521
推荐阅读
相关标签
  

闽ICP备14008679号