Skip to content

Instantly share code, notes, and snippets.

@Integralist Integralist/Go Guru.md
Last active Nov 18, 2018

Embed
What would you like to do?
[Go Guru and Vim-Go] #go #golang #guru #interfaces #vim #vim-go

Go Guru

See official doc: Using Go Guru

go get golang.org/x/tools/cmd/guru
guru -help

Guru command line usage:

guru <mode> <position:byte offset>

Here's an example go program:

type statusHandler int
 
func (s statusHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    code := int(s)
    w.WriteHeader(code)
    io.WriteString(w, http.StatusText(code))
}

With cursor over the statusHandler type:

guru implements ~/code/go/src/github.com/integralist/http-interface/main.go:#812

This tells us that it implements the http.Handler interface:

/Users/markmcdonnell/code/go/src/github.com/integralist/http-interface/main.go:40.6-40.18: basic type statusHandler
/usr/local/Cellar/go/1.10.3/libexec/src/net/http/server.go:82.6-82.12:  implements net/http.Handler

With cursor over the ServeHTTP method:

guru implements ~/code/go/src/github.com/integralist/http-interface/main.go:#836

This tells us that it implements the http.Handler interface's signature ServeHTTP method:

/Users/markmcdonnell/code/go/src/github.com/integralist/http-interface/main.go:42.24-42.32: concrete method func (statusHandler).ServeHTTP(w net/http.ResponseWriter, r *net/http.Request)
/usr/local/Cellar/go/1.10.3/libexec/src/net/http/server.go:83.2-83.10:  implements method (net/http.Handler).ServeHTTP

Note: to convert a line into a byte range you can use in Vim :echo eval(line2byte(line("."))+col("."))


// this is a duplicate of fmt.Stringer interface
type stringit interface {
    String() string
}
 
type testthing struct{}
 
func (t testthing) String() string {
    return "a test thing"
}

With cursor over the testhing type:

guru implements ~/code/go/src/github.com/integralist/http-interface/main.go:#722

This tells us that the testthing struct is satisfying multiple interfaces. This helps me to realize that maybe my new interface isn't necessary and that maybe I should consider re-using an existing interface:

/Users/markmcdonnell/code/go/src/github.com/integralist/http-interface/main.go:33.6-33.14: struct type testthing
/usr/local/Cellar/go/1.10.3/libexec/src/fmt/print.go:62.6-62.13:                           implements fmt.Stringer
/Users/markmcdonnell/code/go/src/github.com/integralist/http-interface/main.go:29.6-29.13: implements stringit
/usr/local/Cellar/go/1.10.3/libexec/src/runtime/error.go:66.6-66.13:                       implements runtime.stringer

With cursor over the interface itself:

guru implements ~/code/go/src/github.com/integralist/http-interface/main.go:#676

This shows us everything that sastifies this interface:

main.go|29 col 6| interface type stringit
/usr/local/Cellar/go/1.10.3/libexec/src/bytes/buffer.go|17 col 6|     is implemented by pointer type *bytes.Buffer
/usr/local/Cellar/go/1.10.3/libexec/src/context/context.go|316 col 6| is implemented by pointer type *context.cancelCtx

...many things satisfy this...

Vim-Go integration with Guru

vim-go uses :GoReferrers to look up references and :GoImplements to show what interface the given type is implementing.

type foo interface {
	bar(string) string
}

type thing struct{}

func (t thing) bar(x string) string {
	fmt.Println(x)
	return "y"
}

If I execute :GoImplements while cursor is on top of bar method, I'll see:

main.go|35 col 16| concrete method func (thing).bar(x string) string
main.go|30 col 2| implements method (foo).bar
  • :GoCallers: lists callers of this function.
  • :GoCallees: lists functions called by this function.
  • :GoReferrers: lists every instance where this function is called.
  • :GoDescribe: lists selected identifiers definition (inc. method set + struct fields).
  • :GoImplements: lists all interfaces the selected identifier satisfies.
  • :GoWhicherrs: lists all possible error types returned.
  • :GoChannelPeers: lists sends/receives on a <- channel.

Vim-Go: Other Features

  • :GoRename: rename all references to identifier across project.
  • :GoImpl: implement stubs for specified interface.
  • :GoDecls: list all function and type declarations for the current file.
  • :GoDef: takes you to the source of the identifier (i.e. where it's defined).
  • :GoTest: run all your tests (can also pass ./...).
  • :GoTestFunc: run the specific test function under your cursor.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.