2017-06-26 2 views
0

Das Folgende ist ein Verfahren neu geschrieben in Kotlin von Java:Vert.x Kotlin Typ passt nicht erforderlich Handler <AsyncResult <Unit>> gefunden (Handler <AsyncResult <Unit>>) -> Einheit

fun publishMessageSource(
     name: String, 
     address: String, 
     completionHandler: Handler<AsyncResult<Unit>> 
) { 
    val record = MessageSource.createRecord(name, address) 
    publish(record, completionHandler) 
} 

Allerdings, wenn ich es so nennen wie folgt:

publishMessageSource("market-data", ADDRESS, { record: Handler<AsyncResult<Unit>> -> 
      if (!record.succeeded()) { 
       record.cause().printStackTrace() 
      } 
      println("Market-Data service published : ${record.succeeded()}") 
     }) 

Ich bekomme den Fehler Type Mismatch required Handler<AsyncResult<Unit>> found (Handler<AsyncResult<Unit>>) -> Unit.

Was mache ich falsch?

Antwort

3

Ihr Lambda sollte den Parameter nehmen, den die einzelne Methode der Handler Schnittstelle nimmt, der in diesem Fall AsyncResult<Unit> ist. Ihr Lambda ist der Handler, so dass es nicht die Handler als Parameter verwendet.

Ich denke, Sie auch hier einen expliziten Aufruf an die SAM-Konstruktor müssen, da Ihre Funktion in Kotlin geschrieben, dass etwas würde wie folgt aussehen:

publishMessageSource("market-data", ADDRESS, Handler<AsyncResult<Unit>> { record: AsyncResult<Unit> -> 
    ... 
}) 

Dieses eine Handler<AsyncResult<Unit>> mit einem Lambda erzeugt darstellt seine einzige Methode.

Schließlich können Sie den Typ innerhalb der Lambda-wegzulassen weniger überflüssig zu sein:

publishMessageSource("market-data", ADDRESS, Handler<AsyncResult<Unit>> { record -> 
    ... 
}) 
+0

Super, danke. Besonders nützliche Informationen über den SAM-Konstruktor. Das habe ich versucht, indem ich den Typ von 'record' im Lambda spezifiziert habe. Ich werde das Zeug auf SAM nochmal lesen. – amb85

+0

Ja, das ist ein bisschen ein seltsamer Anwendungsfall dafür. Standardmäßig funktioniert die SAM-Konvertierung für Java-Interfaces und Java-Methoden, die diese Interfaces verwenden, indem sie einfach ein Lambda notieren, aber den Namen des Interfaces explizit schreiben, bevor das Lambda es auch in diesem Fall zur Verfügung stellt, wenn die Funktion in Kotlin ist. Jetzt, wo ich darüber nachdenke, könntest du deine Funktion dazu bringen, eine richtige Kotlin-Funktion zu übernehmen und dann den Handler darin zu erstellen, um das zu verbessern. – zsmb13

+0

Guter Vorschlag: nicht sicher, warum ich nicht daran gedacht habe. Ich habe für 'resultHandler: (AsyncResult ) -> Unit' und übergeben Sie das als' Handler > (resultHandler) '. Erlaubt mir, den letzten Parameter zu verwenden, ist ein Lambda außerhalb der Klammernotation auch. Ich könnte das nicht tun, wenn ich den SAM-Konstruktor aufrufen würde - ist das einer seiner Nebeneffekte? – amb85

Verwandte Themen