This must be simple, but I've been banging my head against it for half an hour now... Here's my old, exception-unsafe code:
fun isReady(): Boolean {
try {
val cc: CommandChannel = getCommandChannel() // implements AutoCloseable
cc.writeMessage("blahblah")
val response = cc.readMessage() // might throw
cc.close()
if (response.error == null) {
return true
}
} catch (e: ChannelConnectionException) {
}
return false
}
I'd like to rewrite it to use use
, something like this:
fun isReady(): Boolean {
getCommandChannel().use {
try {
it.writeMessage("blahblah")
if (it.readMessage().error == null) {
return true
}
} catch (e: ChannelConnectionException) {
}
return false
}
}
But Kotlin gives me an error:
[ERROR] X.kt:[108,29] Unresolved reference. None of the following candidates is applicable because of receiver type mismatch:
[ERROR] @InlineOnly public inline fun <T : Closeable?, R> ???.use(block: (???) -> ???): ??? defined in kotlin.io
[ERROR] X.kt:[110,17] Unresolved reference: it
[ERROR] X.kt:[111,21] Unresolved reference: it
[ERROR] X.kt:[112,21] 'return' is not allowed here
[ERROR] X.kt:[116,13] 'return' is not allowed here
[ERROR] X.kt:[118,5] A 'return' expression required in a function with a block body ('{...}')
[ERROR] -> [Help 1]
Or, I say "okay I don't understand terse lambda syntax, let me use fun
," and I try this:
fun isReady(): Boolean {
return getCommandChannel().use(fun(cc: CommandChannel): Boolean {
try {
cc.writeMessage("blahblah")
if (cc.readMessage().error == null) {
return true
}
} catch (e: ChannelConnectionException) {
}
return false
})
}
Kotlin still complains:
[ERROR] X.kt:[108,36] Unresolved reference. None of the following candidates is applicable because of receiver type mismatch:
[ERROR] @InlineOnly public inline fun <T : Closeable?, R> ???.use(block: (???) -> Boolean): Boolean defined in kotlin.io
[ERROR]
[ERROR] -> [Help 1]
My current guess is that the problem is that the CommandChannel
I'm trying to use implements AutoCloseable
instead of Closeable
... but I don't know what I'm supposed to do about that! (Is there some sort of adaptor I need to wrap it in, maybe?) Fundamentally, I just want to make sure that cc
's close
method gets called correctly at the end of cc
's scope, so that I'm not leaking connections.
If you look at the Kotlin source,
is available in
kotlin-stdlib
package (source), whereasis available in
kotlin-stdlib-jdk7
(source) package.So, the error that you get :
indicates that since
CommandChannel
implementsAutoCloseable
and notCloseable
, theuse
function appropriate to that is not available in your project. Try adding the dependency of kotlin-stdlib-jdk8 or kotlin-stdlib-jdk7 and you should then be able to use.use{}
forCommandChannel
.