在Go语言中,可以在子函数中使用defer。

huangapple go评论87阅读模式
英文:

Go, is it possible to put defer in sub func

问题

在子函数中使用defer是可能的。

例如,在下面的代码中,你可以将test1()函数中的第12~16行放入子函数中:

func test2() {
    r := subc()
    r.Use()
}

func subc() *Resource {
    r, err := Open("a")
    if err != nil {
        log.Fatalf("error opening 'a'\n")
    }
    defer r.Close()
    return r
}

这样做的行为与test1()函数不同,但你可以在子函数中使用defer来控制变量的恢复和保存。这样,你可以更好地控制是否需要进行整个恢复/保存操作。

希望对你有所帮助!

英文:

Is it possible to put defer in sub function?

I.e., for line 12~16 of func test1() in
https://play.golang.org/p/evabhcjvNs (enclosed below)

Is there any possibility to put them in sub function?
Like what I tried in test2() (but that behavior is different than test1()).

The reason I'm asking is that, for line 12~16 of func test1(), my actual code is to restore the variable from persistent data, then use defer to save it when test1() is done. However, there are cases that the whole restore/save is not necessary, so I'm thinking a better way to control it.

thanks

package main

import "log"

func main() {
	test1()
	log.Printf("==== \n")
	test2()
}

func test1() {
	r, err := Open("a")
	if err != nil {
		log.Fatalf("error opening 'a'\n")
	}
	defer r.Close()

	r.Use()
}

func test2() {
	r := subc()
	r.Use()
}

func subc() *Resource {
	r, err := Open("a")
	if err != nil {
		log.Fatalf("error opening 'a'\n")
	}
	defer r.Close()
	return r
}

type Resource struct {
	name string
}

func Open(name string) (*Resource, error) {
	log.Printf("opening %s\n", name)
	return &Resource{name}, nil
}

func (r *Resource) Use() error {
	log.Printf("using %s\n", r.name)
	return nil
}

func (r *Resource) Close() error {
	log.Printf("closing %s\n", r.name)
	return nil
}

答案1

得分: 6

我想我理解你的问题了。你想知道一个函数是否可以将另一个函数放在调用者的延迟栈上。答案是否定的。解决这个问题的一个可能方法是,让想要延迟执行的函数将该函数返回给调用者,然后由调用者执行defer。例如:

func test2() {
    r, cleanup := subc()
    defer cleanup()
    r.Use()
}

func subc() (*Resource, func()) {
    r, err := Open("a")
    if err != nil {
        log.Fatalf("error opening 'a'\n")
    }
    return r, func() { r.Close() }
}

希望能对你有所帮助!

英文:

I think I understand what you're asking. You want to know if a function can place a function on the defer stack of the caller. The answer to that is no. One possible solution to this is to have the function that wants to defer something return that function to the caller and have the caller do the defer. For example:

func test2() {
    r, cleanup := subc()
    defer cleanup()
    r.Use()
}

func subc() (*Resource, func()) {
    r, err := Open("a")
    if err != nil {
        log.Fatalf("error opening 'a'\n")
    }
    return r, func() { r.Close() }
}

huangapple
  • 本文由 发表于 2016年12月4日 06:34:44
  • 转载请务必保留本文链接:https://go.coder-hub.com/40953241.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定