Hey, people In swift they have <defer>. Do we have...
# feed
v
Hey, people In swift they have defer. Do we have something same in kotlin? I mean build-in thing, not finally in try-catch
s
🤔 the
finally
block is Kotlin's built-in solution for this, so I'm not sure what you mean
There is also the
use
function for
Closeable
resources, if you're looking for something more concise. But it just uses try-finally under the hood.
v
@Sam if I want to use
finally
i need to use
try-catch
. An if I do not want to catch any exception in same method - this will be ridiculous to catch exception and then throw it, just to get an access to finally. Did you really get a chance to look into the link that I shared?
Copy code
fun foo() {
    // do some logic, open some usb socket do something.

    defer {
        // close all connections 
    }
}
This is the idea, this is how they are doing that
g
There is nothing like this in Kotlin, but one can easily write a DSL for this, but you have to wrap your code with this block to support it: fun foo() = withDefer { defer { doSomething() } }
s
What makes you say that you need
catch
to use
finally
? That's not true, you can use
try
with
finally
and no
catch
.
Copy code
fun foo() {
  try {
    doStuff()
  } finally {
    // close connections
  }
}
g
try/finally is the only out of the box way to close resources + Closeable.use() helper method
v
@gildor yeah, thanks. This is something that I am using currently, pretty same 🙂
@Sam This is exactly what I am saying. This is what we have:
Copy code
fun foo() {
    try {
        // do some logic, open some usb socket do something.
    } finally {
        // close all connections
    }
}
This is what I want:
Copy code
fun foo() {
    // do some logic, open some usb socket do something.

    defer {
        // close all connections
    }
}
Don’t you see that second option looks nicer?
s
Personally, I prefer Kotlin's approach, because it makes it super clear which scope the deferred cleanup applies to. But different programming languages have different syntax, that's just the way it goes.
a
Arrow has two implementations of this idea: autoClose if you don't need coroutine support (https://apidocs.arrow-kt.io/arrow-autoclose/arrow/index.html) and Resource if you want good integration with cancellation and so on https://arrow-kt.io/learn/coroutines/resource-safety/
☝️ 2
v
@Sam true, right. I have super specific case with super specific usb device connected to the phone. And I found that swift build-in things could make my code a bit cleaner. I already have bunch try-catch-finally and don’t like that.
@Alejandro Serrano.Mena Thanks for links, let me check that!
k
Let me try to understand this. Since
defer { block }
in Swift translates directly to
finally { block }
in Kotlin, the only thing that's different is that you don't like the word
try
? I actually think it's helpful, as it immediately tells us that the enclosed code is subject to cleanup. Without
try
, as in Swift, we would have to scan the whole function to see if there was a
finally
(or
defer
) in that block.
g
@Klitos Kyriacou Swift/Golang defer is not the same as finally though, it allows to call as many block as you want anywhere in the function, it's just has the same use case
k
@gildor Thanks, now I can see an advantage: you can put
defer
straight after each resource that you've opened, which is something you can't do with
finally
.
👌 2
🔥 1
c
^ It was already mentioned in this thread, but Arrow's Resource allows to co-locate creation and freeing as well
💯 1
m
the other nice thing with
defer
is only the cleanup code is indented. With both
try/finally
and
use
the use of the resource goes into the
{}
. So it looks a little nicer, but the Kotlin code executes in the vertical order so it is probably easier to understand the execution order.
👍 1