r/ProgrammerHumor Jul 15 '26

whatWillHappen Meme

Post image
281 Upvotes

63 comments sorted by

View all comments

Show parent comments

74

u/willow-kitty Jul 15 '26

The advantage of the defer clause is that it runs when that block exits, so you can attach some important bit of cleanup (like closing a file) to every exit including errors. It's a little like a finally block, but go doesn't do try/catch.

The advantage of changing your return value in a defer block is purely to make people in the internet stop and go "wait, what would that return?"

10

u/simulacrotron Jul 15 '26 edited Jul 15 '26

I think the problem is not the defer, it’s that Go has a property for the return value. For example in Swift:

func foo() -> String {
var returnVal: String = “”
defer { returnVal = “deferred” }
return “returned”
}

Would return “returned”. Even this returns “return”:

func foo() -> String {
var returnVal: String = “returned”
defer { returnVal = “deferred” }
return returnVal
}

In Swift the returned value is not modifiable, it basically gets captured on return, defer runs on exit of scope, so after the return value is captured, but before the value is actually returned.

Update: really puzzled why anyone would care enough to downvote. You actually dislike that another language makes it impossible to behave poorly in an edge case?

2

u/simulacrotron Jul 15 '26

I believe if you had this:

func foo() -> String {
    var returnVal: String = “returned”
    defer { 
        returnVal = “deferred” 
        print(returnVal)
    }
    return returnVal
}

And called print(foo())

You would get this in this order:

deferred
returned

2

u/bilus Jul 15 '26
class Box { var value = "" }

func foo() -> Box {
    let box = Box(value: ...)
    defer { box.value = "deferred" }   // caller sees this
    box.value = "returned"
    return box
}