1
votes

Fonction Lambdas Kotlin et type Mismatch

J'essaye de porter une fonction de java vers kotlin mais j'ai pas mal de problèmes. Le code java original est le suivant:

Type mismatch: inferred type is (???) -> Unit but OnTaskCompletedListener<???> was expected

Ceci est mon code converti kotlin:

setOnTaskCompletedListener(task, { result ->
    val s = result.getText()
    reco.close()
    Log.i(logTag, "Recognizer returned: " + s)
    setRecognizedText(s)
  })

et c'est là que mon code renvoie l'erreur:

private fun <T> setOnTaskCompletedListener(task:Future<T>, listener: OnTaskCompletedListener<T>){
  s_executorService.submit({ 
    val result = task.get()
    listener.onCompleted(result)
  });
}

J'obtiens cette erreur sur le "{result -> ...}":

setOnTaskCompletedListener(task, result -> {
                final String s = result.getText();
                reco.close();
                Log.i(logTag, "Recognizer returned: " + s);
                setRecognizedText(s);
            });

private <T> void setOnTaskCompletedListener(Future<T> task, OnTaskCompletedListener<T> listener) {
    s_executorService.submit(() -> {
        T result = task.get();
        listener.onCompleted(result);
        return null;
    });
}

Suis-je fait quelque chose de mal?


0 commentaires

3 Réponses :


0
votes

C'est probablement parce que votre méthode setRecognizedText est void ou Unit et c'est la dernière expression de ce bloc (c'est donc ce qui sera renvoyé - Unit est la version Kotlin de Void )

Dans le code Java, vous retournez null - vous devriez faire de même, mais pensez à y réfléchir à nouveau car cela ressemble à une odeur de code


4 commentaires

Ce code java provient du SDK cognitif de Microsoft. Je ne suis sincèrement pas satisfait de cette structure mais je ne suis pas un développeur kotlin, donc je fais de mon mieux. L'ensemble reconnaissant le texte a cependant une réponse unitaire


L'ensemble reconnaissant le texte a en fait une réponse unitaire - c'est ce dont je parle - ce bloc devrait renvoyer OnTaskCompletedListener


Cependant, la fonction d'origine ne renvoie pas de toute façon un OnTaskCompletedListener donc je ne comprends pas pourquoi il donne cette erreur.


Peu importe - vous avez return null à la fin



0
votes

Si vous transformez votre code en kotlin, sans java interop, il serait préférable d'utiliser lambda car cela supprime l'utilisation de toutes les interfaces standard.

inline private fun <T> setOnTaskCompletedListener(task:Future<T>, listener: (T) -> Unit){

EDIT: strong > Depuis l'utilisation de lambda, vous pouvez augmenter l'efficacité de votre application si vous utilisez un modificateur en ligne

private fun <T> setOnTaskCompletedListener(task:Future<T>, listener: (T) -> Unit){
  s_executorService.submit({ 
    val result = task.get()
    listener(result)
  });
}

//call
setOnTaskCompletedListener(task, { result ->
    val s = result.getText()
    reco.close()
    Log.i(logTag, "Recognizer returned: " + s)
    setRecognizedText(s)
  })


1 commentaires

cela semble fonctionner (pas d'erreur de compilation pour le moment) mais je n'en suis pas complètement sûr



0
votes

Dans la méthode ci-dessous, vous avez mentionné listener: OnTaskCompletedListener comme paramètre d'objet.

setOnTaskCompletedListener(task,object:OnTaskCompletedListener< /*your T type*/>{ 
    override fun yourInterfaceMethod(result:ResultType) {
        val s = result.getText()
        reco.close()
        Log.i(logTag, "Recognizer returned: " + s)
        setRecognizedText(s)
      }
     })

mais en l'appelant, vous passez un lambda param

setOnTaskCompletedListener(task, { result ->
    val s = result.getText()
    reco.close()
    Log.i(logTag, "Recognizer returned: " + s)
    setRecognizedText(s)
  })

convertir le code ci-dessus en transformant lambda en une classe anonyme comme celle-ci

private fun <T> setOnTaskCompletedListener(task:Future<T>, listener: OnTaskCompletedListener<T>){
  s_executorService.submit({ 
    val result = task.get()
    listener.onCompleted(result)
  });
}


3 commentaires

J'ai essayé cette solution mais cela m'a donné une erreur sur le mot-clé de l'objet


À l'intérieur de la classe anonyme, implémentez la méthode d'interface.


@CristianBregant J'ai édité ma réponse. Vérifiez-le.