wtf

198 views
Skip to first unread message

Aln Kapa

unread,
Aug 26, 2023, 10:58:06 AM8/26/23
to golang-nuts
Hi All !
Need some help, what am I doing wrong?


// You can edit this code!
// Click here and start typing.
package main

import (
"errors"
"fmt"
)

type process struct {
}

func (p *process) close(err error) {
if err != nil {
fmt.Println("error")
} else {
fmt.Println("no error")
}
}
func Handle(b bool) {
p := process{}
var err error
defer func() {
p.close(err)
}()
if b {
err = errors.New("err")
}
}

func HandleWTF(b bool) {
p := process{}
var err error
defer p.close(err)
if b {
err = errors.New("err")
}
}

func main() {
Handle(true)    // error
Handle(false)   // no error
HandleWTF(true) // no error ?????????
}

Brian Candler

unread,
Aug 26, 2023, 11:10:08 AM8/26/23
to golang-nuts
Any arguments to defer functions are evaluated at the time that the defer is executed.  In HandleWTF, defer p.close(err) is called immediately after err is declared with value nil, so nil is what is used.

From the specification:

"Each time a "defer" statement executes, the function value and parameters to the call are evaluated as usual and saved anew but the actual function is not invoked."

Aln Kapa

unread,
Aug 26, 2023, 11:37:43 AM8/26/23
to golang-nuts

Well here is the code that works as I need, what is wrong with the previous one ?


package main

import (

"fmt"
)

type process struct {
}

func (p *process) close(err any) {
v, _ := err.(*int)
if *v == 1 {

fmt.Println("error")
} else {
fmt.Println("no error")
}
}
func Handle(b bool) {
p := process{}
var i = 2
var pt any = &i
defer func() {
p.close(pt)
}()
if b {
i = 1

}
}

func HandleWTF(b bool) {
p := process{}
var i = 2
var pt any = &i
defer p.close(pt)
if b {
i = 1

}
}

func main() {
Handle(true)    // error
Handle(false)   // no error
HandleWTF(true) // error
}


--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/25846715-b3bf-4d1d-81b4-4a2799e69d27n%40googlegroups.com.

Brian Candler

unread,
Aug 26, 2023, 11:47:46 AM8/26/23
to golang-nuts
In both cases, the argument inside parenthesis is evaluated at the time "defer" is executed - as indeed is the value of "p".

In the first case, you wrote "defer p.close(err)".  Since err is nil at this point, at the end of the function body, p.close(nil) is called.

In the second case, you wrote "defer p.close(pt)" where pt is a pointer to some variable. Therefore, at the end of the function body, p.close(pt) is called, with the value of the pointer at that time.

Since in the second case you have a valid pointer to some data, then you can modify that data through the pointer. Note that if the pointer pt had changed, it would still be referring to the original value of pt, since that was captured at the time "defer" was called.

Maybe this clarifies?

Aln Kapa

unread,
Aug 26, 2023, 1:10:23 PM8/26/23
to golang-nuts
I understand, thanks.

Reto

unread,
Aug 27, 2023, 10:54:01 AM8/27/23
to golan...@googlegroups.com
On Sat, Aug 26, 2023 at 07:56:30AM -0700, Aln Kapa wrote:
> Need some help, what am I doing wrong?

You don't understand how defer works would be my guess

> func main() {
> Handle(true) // error
> Handle(false) // no error
> HandleWTF(true) // no error ?????????

Why do you expect this to print an error?
The deferred call's arguments are evaluated immediately, but the function call is not executed until the surrounding function returns.

At the time it is evaluated, err is nil

Jonathan

unread,
Aug 27, 2023, 5:41:41 PM8/27/23
to golang-nuts

Defer evaluates the arguments to the deferred func at the point  of the defer statement.
Reply all
Reply to author
Forward
0 new messages