0

The following is a method rewritten in Kotlin from Java:

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

However, when I call it as follows:

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

I get the error Type Mismatch required Handler<AsyncResult<Unit>> found (Handler<AsyncResult<Unit>>) -> Unit.

What am I doing wrong?

junglie85
  • 1,243
  • 10
  • 30

1 Answers1

3

Your lambda should take the parameter that the single method of the Handler interface takes, which is AsyncResult<Unit> in this case. Your lambda is the Handler, so it doesn't take the Handler as a parameter.

I think you'll also need an explicit call to the SAM constructor here, since your function is written in Kotlin, that would look something like this:

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

This creates a Handler<AsyncResult<Unit>> with a lambda representing its single method.

Finally, you can omit the type inside the lambda to be less redundant:

publishMessageSource("market-data", ADDRESS, Handler<AsyncResult<Unit>> { record ->
    ...
})
zsmb13
  • 85,752
  • 11
  • 221
  • 226
  • Awesome, thanks. Especially useful info about the SAM constructor. That's what I was trying to achieve with specifying the type of `record` in the lambda. I'll go re-read the stuff on SAM. – junglie85 Jun 26 '17 at 20:25
  • Yeah, this is a bit of a weird use case for it. By default SAM conversion works for Java interfaces and Java methods that take those interfaces by just writing down a lambda, but explicitly writing the name of the interface before the lambda makes it available in this case too, when the function is in Kotlin. Now that I think of it, you could make your function take a proper Kotlin function and then create the Handler inside it to make this neater. – zsmb13 Jun 26 '17 at 20:49
  • Good suggestion: not too sure why I didn't think of that. I've gone for `resultHandler: (AsyncResult) -> Unit` and pass that on as a `Handler>(resultHandler)`. Allows me to use the last parameter is a lambda outside of the brackets notation too. I couldn't do that when calling the SAM constructor - is that one of its side effects? – junglie85 Jun 26 '17 at 23:11
  • Yes, indeed, you can do that with SAM conversion, but not with an explicit SAM constructor. – zsmb13 Jun 27 '17 at 03:52