找不到类型org.apache.flink.api.common.typeinfo.TypeInformation [...]的证据参数的隐含值

时间:2016-06-20 10:21:17

标签: scala apache-flink flink-streaming

我正在尝试为Apache Flink编写一些用例。我经常遇到的一个错误是

could not find implicit value for evidence parameter of type org.apache.flink.api.common.typeinfo.TypeInformation[SomeType]

我的问题是,当它们发生时以及它们不发生时,我无法确定它们。

最近的一个例子是以下

...
val largeJoinDataGen = new LargeJoinDataGen(dataSetSize, dataGen, hitRatio)
val see = StreamExecutionEnvironment.getExecutionEnvironment
val newStreamInput = see.addSource(largeJoinDataGen)
...

其中LargeJoinDataGen extends GeneratorSource[(Int, String)]GeneratorSource[T] extends SourceFunction[T]都在单独的文件中定义。

尝试构建时,我得到了

Error:(22, 39) could not find implicit value for evidence parameter of type org.apache.flink.api.common.typeinfo.TypeInformation[(Int, String)]
val newStreamInput = see.addSource(largeJoinDataGen)

1。为什么给定示例中存在错误?

2。当这些错误发生时以及如何在将来避免这些错误时,一般指导原则是什么?

P.S。:第一个scala项目和第一个flink项目,请耐心等待

3 个答案:

答案 0 :(得分:39)

您可以进行导入而不是隐含

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

它也会有所帮助。

答案 1 :(得分:11)

这主要发生在您拥有用户代码时,即源或地图函数或具有通用参数的那种性质的东西。在大多数情况下,您可以通过添加类似

的内容来解决此问题
implicit val typeInfo = TypeInformation.of(classOf[(Int, String)])

如果您的代码位于另一个具有泛型参数的方法中,您还可以尝试添加绑定到方法的泛型参数的上下文,如

def myMethod[T: TypeInformation](input: DataStream[Int]): DataStream[T] = ...

答案 2 :(得分:9)

  

我的问题是,当它们发生时以及它们不发生时,我无法确定它们。

当需要implicit parameter时,就会发生这种情况。如果我们看一下方法定义,我们会看到:

def addSource[T: TypeInformation](function: SourceFunction[T]): DataStream[T]

但我们没有看到任何隐式参数定义,它在哪里?

当你看到一个多态方法,其中type参数的格式为

def foo[T : M](param: T)

其中T是类型参数,Mcontext bound。这意味着该方法的创建者正在请求类型为M[T]的隐式参数。它相当于:

def foo[T](param: T)(implicit ev: M[T])

对于您的方法,它实际上扩展为:

def addSource[T](function: SourceFunction[T])(implicit evidence: TypeInformation[T]): DataStream[T]

这就是你看到编译器抱怨的原因,因为它无法找到方法所需的隐式参数。

如果我们转到Apache Flink Wiki,在Type Information下我们可以看到为什么会发生这种情况:

  

证据参数错误没有隐含值

     

如果无法创建TypeInformation,则程序无法编译,并显示错误,指出“无法找到TypeInformation类型的证据参数的隐式值。”   如果尚未导入生成TypeInformation的代码的常见原因。 确保导入整个flink.api.scala包。   import org.apache.flink.api.scala ._

对于通用方法,您还需要在呼叫站点生成TypeInformation

  

对于泛型方法,函数参数和返回类型的数据类型对于每个调用可能不相同,并且在定义方法的站点处不知道。上面的代码将导致错误,即没有足够的隐式证据可用。   在这种情况下,必须在调用站点生成类型信息并将其传递给方法。 Scala为此提供了隐式参数。

对于你的类型,这意味着如果调用方法是通用的,它还需要请求绑定它的类型参数的上下文。