我正在尝试为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项目,请耐心等待
答案 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
是类型参数,M
是context 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为此提供了隐式参数。
对于你的类型,这意味着如果调用方法是通用的,它还需要请求绑定它的类型参数的上下文。