2016-06-20 19 views
7

Sto cercando di scrivere alcuni casi d'uso per Apache Flink. Un errore a cui mi imbatto abbastanza spesso ènon è stato in grado di trovare il valore implicito per parametro evidence di tipo org.apache.flink.api.common.typeinfo.TypeInformation [...]

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

Il mio problema è che non posso davvero inchiodare quando accadono e quando non lo fanno.

L'esempio più recente di questo sarebbe il seguente

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

dove LargeJoinDataGen extends GeneratorSource[(Int, String)] e GeneratorSource[T] extends SourceFunction[T], entrambe definite in file separati.

Quando si cerca di costruire questo ho

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. Perché c'è un errore nel esempio dato?

2. Quale sarebbe una linea guida generale quando si verificano questi errori e come evitarli in futuro?

P.S .: primo progetto Scala e primo progetto Flink quindi per favore sii paziente

risposta

6

Ciò accade soprattutto quando si dispone di codice utente, vale a dire una fonte o una funzione mappa o qualcosa del genere che ha un parametro generico. Nella maggior parte dei casi è possibile rimediare con l'aggiunta di qualcosa di simile

implicit val typeInfo = TypeInformation.of(classOf[(Int, String)]) 

Se il codice è all'interno di un altro metodo che ha un parametro generico si può anche provare ad aggiungere un contesto legato al parametro generico del metodo, come in

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

questa soluzione sembra funzionare. la chiamata al metodo è 'TypeInformation.of (classOf [(Int, String)])', potresti volerlo aggiustare nella tua risposta. – jheyd

5

Il mio problema è che non posso davvero inchiodare quando accadono e quando non lo fanno.

Si verificano quando è richiesto un implicit parameter. Se guardiamo la definizione del metodo vediamo:

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

Ma non vediamo alcun parametro implicito definito, dove si trova?

quando si vede un metodo polimorfico dove il parametro tipo è di forma

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

Dove T è il parametro tipo e M è un context bound. Significa che il creatore del metodo richiede un parametro implicito di tipo M[T]. E 'equivalente a:

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

Nel caso del metodo, in realtà è estesa a:

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

Questo è il motivo per cui si vede il compilatore lamentarsi, in quanto non riesce a trovare il parametro implicito il metodo sta richiedendo.

Se andiamo al Apache Flink Wiki, sotto Type Information possiamo capire perché questo accade:

Nessun valore implicito per prove di parametro Errore

Nel caso in cui non poteva essere creato TypeInformation, programmi impossibile compilare con un errore che indica che "non è stato in grado di trovare il valore implicito per il parametro evidence di tipo TypeInformation". Un motivo frequente se il codice che genera lo TypeInformation non è stato importato. Assicurarsi di importare l'intero pacchetto flink.api.scala. importazione org.apache.flink.api.scala._

Per i metodi generici, avrete bisogno di chiedere loro di generare un TypeInformation al call-sito così:

Per metodi generici, i tipi di dati dei parametri di funzione e il tipo di ritorno potrebbero non essere gli stessi per ogni chiamata e non sono noti nel sito in cui è definito il metodo. Il codice sopra provocherà un errore che non sono disponibili prove implicite sufficienti. In questi casi, le informazioni sul tipo devono essere generate nel sito di chiamata e passate al metodo. Scala offre parametri impliciti per questo.

Per i tipi, ciò significa che se il metodo di richiamo è generico, deve anche richiedere il contesto associato per il parametro di tipo.

+1

'org.apache.flink.api.scala._' era già importato e succede ancora. Questo è quello che intendevo con "non inchiodare". – jheyd

+1

@jheyd Richiede 'GeneratorSource [T]' e 'SourceFunction [T]' per avere anche i limiti di contesto: 'GeneratorSource [T: TypeInformation]', 'SourceFunction [T: TypeInformation]' –

+1

SourceFunction è un'interfaccia java richiesta dal metodo addSource, aggiungendo limiti di contesto a GeneratorSource non ha modificato nulla. – jheyd

10

si può fare un import, invece di impliciti

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

Essa aiuterà anche.