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

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

我正在尝试为 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项目所以请耐心等待

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

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

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

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

My problem is that I cant really nail down when they happen and when they dont.

它们在需要 implicit parameter 时发生。如果我们查看方法定义,我们会看到:

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

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

当您看到一个多态方法,其中类型参数的形式为

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 下我们可以看到为什么会这样:

No Implicit Value for Evidence Parameter Error

In the case where TypeInformation could not be created, programs fail to compile with an error stating “could not find implicit value for evidence parameter of type TypeInformation”. A frequent reason if that the code that generates the TypeInformation has not been imported. Make sure to import the entire flink.api.scala package. import org.apache.flink.api.scala._

对于泛型方法,您还需要要求它们在调用站点生成 TypeInformation

For generic methods, the data types of the function parameters and return type may not be the same for every call and are not known at the site where the method is defined. The code above will result in an error that not enough implicit evidence is available. In such cases, the type information has to be generated at the invocation site and passed to the method. Scala offers implicit parameters for that.

请注意,import org.apache.flink.streaming.api.scala._ 可能也是必需的。

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

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

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

这也会有帮助。

例如 Scala 版本(2.11、2.12 等)不是二进制兼容的。

即使使用import org.apache.flink.api.scala._以下也是错误的配置:

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <scala.version>2.12.8</scala.version>
        <scala.binary.version>2.11</scala.binary.version>
    </properties>

Maven 中的正确配置:

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <scala.version>2.12.8</scala.version>
        <scala.binary.version>2.12</scala.binary.version>
    </properties>