Skip to content

Instantly share code, notes, and snippets.

@tenntenn
Last active January 2, 2017 15:06
Show Gist options
  • Save tenntenn/b29469b067142d0db7893fca0552eb41 to your computer and use it in GitHub Desktop.
Save tenntenn/b29469b067142d0db7893fca0552eb41 to your computer and use it in GitHub Desktop.
Goのスコープについて考えてみよう #golang ref: http://qiita.com/tenntenn/items/ac5940dfbca703183fdf
package main
import "fmt"
func main() {
const message = "hello, world"
fmt.Println(message)
}
package main
import (
myfmt "fmt"
)
func main() {
var string string = "HELLO"
myfmt.Println(string)
}
fset := token.NewFileSet()
f, err := parser.ParseFile(fset, "sample.go", src, 0)
if err != nil {
log.Fatalln("Error:", err)
}
conf := types.Config{Importer: importer.Default()}
pkg, err := conf.Check("main", fset, []*ast.File{f}, nil)
if err != nil {
log.Fatalln("Error:", err)
}
ast.Inspect(f, func(n ast.Node) bool {
if ident, ok := n.(*ast.Ident); ok {
// TODO: 識別子のスコープを取得する
}
return true
})
innerMost := pkg.Scope().Innermost(ident.Pos())
s, _ := innerMost.LookupParent(ident.Name, ident.Pos())
package main
import (
"fmt"
"go/ast"
"go/importer"
"go/parser"
"go/token"
"go/types"
"log"
)
// sample.go
const src = `package main
import "fmt"
func main() {
const message = "hello, world"
fmt.Println(message)
}`
func main() {
fset := token.NewFileSet()
f, err := parser.ParseFile(fset, "sample.go", src, 0)
if err != nil {
log.Fatalln("Error:", err)
}
conf := types.Config{Importer: importer.Default()}
pkg, err := conf.Check("main", fset, []*ast.File{f}, nil)
if err != nil {
log.Fatalln("Error:", err)
}
scopes := map[*types.Scope]struct{}{}
ast.Inspect(f, func(n ast.Node) bool {
if ident, ok := n.(*ast.Ident); ok {
innerMost := pkg.Scope().Innermost(ident.Pos())
s, _ := innerMost.LookupParent(ident.Name, ident.Pos())
if s != nil {
scopes[s] = struct{}{}
}
}
return true
})
fmt.Println("====", len(scopes), "scopes ====")
for s := range scopes {
fmt.Println(s)
}
}
==== 3 scopes ====
package "main" scope 0x4203ff6d0 {
. func main.main()
}
sample.go scope 0x4203ff7c0 {
. package fmt
}
function scope 0x42053d630 {
. const message untyped string
}
package main
import (
myfmt "fmt"
)
func main() {
var string string = "HELLO"
myfmt.Println(string)
}
==== 4 scopes ====
package "main" scope 0x4203ff6d0 {
. func main.main()
}
sample.go scope 0x4203ff7c0 {
. package myfmt ("fmt")
}
universe scope 0x4203fe1e0 {
. builtin append
. type bool bool
. type byte byte
. builtin cap
. builtin close
. builtin complex
. type complex128 complex128
. type complex64 complex64
. builtin copy
. builtin delete
. type error interface{Error() string}
. const false untyped bool
. type float32 float32
. type float64 float64
. builtin imag
. type int int
. type int16 int16
. type int32 int32
. type int64 int64
. type int8 int8
. const iota untyped int
. builtin len
. builtin make
. builtin new
. nil
. builtin panic
. builtin print
. builtin println
. builtin real
. builtin recover
. type rune rune
. type string string
. const true untyped bool
. type uint uint
. type uint16 uint16
. type uint32 uint32
. type uint64 uint64
. type uint8 uint8
. type uintptr uintptr
}
function scope 0x42053d630 {
. var string string
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment