====== Useful Go ====== ===== Installing ===== Go to https://golang.org/dl/ and look for your system: wget your_binary sudo tar -xvf <> sudo mv go /usr/local/ export GOROOT=/usr/local/go export GOPATH=$HOME/gopath export PATH=$GOPATH/bin:$GOROOT/bin:$PATH To check: go version go env ===== Projects ===== ==== go mod for managing dependences ==== After Go 1.11. go mod init # Do not do it in the GOPATH When you do ''go build'' it downloads dependencies automatically. There will appear ''go.mod'' y ''go.sum'' files. The first one to list dependences, the second one the checksums. go mod tidy # To remove non-used libraries go mod vendor # To vendor dependencies in vendor directory. Then, if you added a new package to your project, to use them: import "project/package" ==== dep tool for managing dependences (DEPRECATED) ==== To install: ''apt install go-dep''. To initialize a project: $ export GOPATH=`pwd` $ mkdir src $ cd src $ mkdir marcarrodes $ cd marcarrodes $ dep init * The Gopkg.toml file is where you specify your dependencies and the particular versions of these dependencies that you wish your project to use. * The Gopkg.lock file is a transitively complete snapshot of your project’s dependency graph. * The vendor/ directory is where your dependencies are stored. It’s the equivalent to the node_modules/ It's commands: * ''init'' Sets up a new Go project. * ''status'' Reports the status of a project’s dependencies. * ''ensure'' Ensures a dependency is safely vendored in the project. * ''prune'' Prunes your dependencies, this is also done automatically by ensure. * ''version'' Shows the dep version information. Add a dependence: $ dep ensure -add github.com/foo/bar github.com/another/project ... Update dependence: // dry run testing an update $ dep ensure -update -n // non-dry run $ dep ensure -update // updates a specific package $ dep ensure -update github.com/gorilla/mux // updates to a specific version $ dep ensure -update github.com/gorilla/mux@1.0.0 ==== Project layout ==== * This section was written following this guidE: https://github.com/golang-standards/project-layout Folders you could have: * ''cmd'' **Main applications for this project.** The directory name for each application should match the name of the executable you want to have (e.g., /cmd/myapp). Don't put a lot of code in the application directory. **If you think the code can be imported and used in other projects, then it should live in the /pkg directory.** **If the code is not reusable or if you don't want others to reuse it, put that code in the /internal directory.** It's common to have a small main function. * ''internal'' Private application and library code. This is the code you don't want others importing in their applications or libraries. Put your actual application code in the /internal/app directory (e.g., /internal/app/myapp) and the code shared by those apps in the /internal/pkg directory (e.g., /internal/pkg/myprivlib). * ''pkg'' Library code that's ok to use by external applications (e.g., /pkg/mypubliclib). Other projects will import these libraries expecting them to work, so think twice before you put something here. * ''vendor'' Application dependencies. Others: * ''api'' OpenAPI/Swagger specs, JSON schema files, protocol definition files. * ''web'' Web application specific components: static web assets, server side templates and SPAs. * ''configs'' Configuration file templates or default configs. * ''init'' System init (systemd, upstart, sysv) and process manager/supervisor (runit, supervisord) configs. * ''scripts'' Scripts to perform various build, install, analysis, etc operations. * ''build'' * ''deployments'' * ''test'' * ''doc'' * ''tools'' Supporting tools for this project. * ''examples'' * ''third_party'' * ''githooks'' * ''assets'' * ''website'' You do not have to have a ''src'' directory. ---- ====== Gotchas ====== ===== Basic ===== // Define a string array variable var ( viewNames = []string{"projects", "generations", "info", "menu"} ) // Loop over an slice for _, v := range viewNames { fmt.Println(v) } // Get a variable without using it _, err := g.SetCurrentView(name) ===== Conversions ===== Previous code: import "strconv" Code // String to byte[] buff := []byte("Here is a string....") // Byte to String str := string(buff) // Int to string str := strconv.Itoa(currentNumber) ===== Program ===== Previous code used: import "os" Code: argumentsWithoutProgramName = os.Args[1:] settings_path = os.Getenv("GLOUDVIEWER_CONFIG") ===== Arrays (or, in Go: Slices) ===== len(arr) ===== Maps ===== var m map[string]Vertex m = make(map[string]Vertex) m["Bell Labs"] = Vertex{40.68433, -74.39967} keys := make([]keyType, 0, len(myMap)) values := make([]valueType, 0, len(myMap)) for k, v := range myMap { keys = append(keys, k) values = append(values, v) } ===== Go Routines ===== Previous code used: func f(from string) { for i := 0; i < 3; i++ { fmt.Println(from, ":", i) } } Code: // Call a function as a goroutine go f("goroutine") // Call a function as goroutine at the same time we define it go func(msg string) { fmt.Println(msg) }("going") ===== Not so common types ===== Previous code: import "bytes" Code: // String buffer buf := bytes.NewBufferString("") fmt.Fprintln(buf, "Hello!") str := buf.String() ===== JSON ===== Previous code used: import "io/ioutil" import "encoding/json" type Generation struct { Project string Author string `json:"author"` Version string `json:"version"` } Code: // JSON file to struct object b, err := ioutil.ReadFile(path) if err != nil { panic(err) } generation := Generation{} json.Unmarshal(b, &generation) ===== Filesystem ===== Previous code: import "strings" import "path" import "path/filepath" Code: // info is info os.FileInfo type // Is a directory: info.IsDir() // Get parent path from a path (pth) filepath.Dir(pth) // File name without extension: strings.TrimSuffix(info.Name(), pth.Ext(info.Name()) // Join path path.Join(arguments[0], selectedProject) ====== Snippets ====== ===== Map, reduce, filter in Go ===== func mapXtoY(collection []X, fn func(elem X) Y) []Y { var result []Y for _, item := range collection { result = append(result, fn(item)) } return result } func reduceXtoY(collection []X, init Y, fn func(memo Y, elem X) Y) Y { result := init for _, item := range collection { result = fn(result, item) } return result } func filterXs(collection []X, fn func(elem X) bool) []X { var result []X for _, item := range collection { if fn(item) { result = append(result, item) } } return result } ===== Nested functions ===== func f() { foo := func(s string) { fmt.Println(s) } foo("Hello World!") }