0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

[golang] 遅延評価、即時評価を理解する。

Posted at

目的

遅延評価、即時評価を理解する。

検証

main.go
package main

import (
	"fmt"
	"time"
)

//go:noinline
func Demo() func(int) {
	aaa := 333
	bbb := 444

	closure := func(n int) {
		fmt.Println("クロージャの中で見る aaa: ", aaa)
		fmt.Println("クロージャの中で見る n: ", n)
	}

	defer func(n int) {
		fmt.Println("deferの中で見る aaa: ", aaa)
		fmt.Println("deferの中で見る bbb: ", n)
	}(bbb)

	aaa = 666
	bbb = 888

	closure(bbb)

	go func() {
		time.Sleep(time.Second * 3)
		aaa = 1000
	}()

	return closure
}

//go:noinline
func main() {
	myfunc := Demo()
	myfunc(100)
	time.Sleep(time.Second * 5)
	myfunc(200)
}

~/praprago$ go run main.go
クロージャの中で見る aaa:  666
クロージャの中で見る n:  888
deferの中で見る aaa:  666
deferの中で見る bbb:  444
クロージャの中で見る aaa:  666
クロージャの中で見る n:  100
クロージャの中で見る aaa:  1000
クロージャの中で見る n:  200

注目すべきは、./main.go:10:2: moved to heap: aaa の部分です。
クロージャが return されるので、それに備えて、aaa をヒープにエスケープしてます。

~/praprago$ go build -gcflags "-m=1" main.go
# command-line-arguments
./main.go:13:13: can inline Demo.func1
./main.go:18:8: can inline Demo.func2
./main.go:18:2: can inline Demo.deferwrap1
./main.go:28:5: can inline Demo.func3
./main.go:26:9: inlining call to Demo.func1
./main.go:26:9: inlining call to fmt.Println
./main.go:26:9: inlining call to fmt.Println
./main.go:14:14: inlining call to fmt.Println
./main.go:15:14: inlining call to fmt.Println
./main.go:19:14: inlining call to fmt.Println
./main.go:20:14: inlining call to fmt.Println
./main.go:10:2: moved to heap: aaa
./main.go:13:13: func literal escapes to heap
./main.go:14:14: ... argument does not escape
./main.go:14:15: "クロージャの中で見る aaa: " escapes to heap
./main.go:14:55: aaa escapes to heap
./main.go:15:14: ... argument does not escape
./main.go:15:15: "クロージャの中で見る n: " escapes to heap
./main.go:15:53: n escapes to heap
./main.go:18:8: func literal does not escape
./main.go:19:14: ... argument does not escape
./main.go:19:15: "deferの中で見る aaa: " escapes to heap
./main.go:19:45: aaa escapes to heap
./main.go:20:14: ... argument does not escape
./main.go:20:15: "deferの中で見る bbb: " escapes to heap
./main.go:20:45: n escapes to heap
./main.go:26:9: ... argument does not escape
./main.go:26:9: "クロージャの中で見る aaa: " escapes to heap
./main.go:26:9: aaa escapes to heap
./main.go:26:9: ... argument does not escape
./main.go:26:9: "クロージャの中で見る n: " escapes to heap
./main.go:26:9: n escapes to heap
./main.go:28:5: func literal escapes to heap
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?