====== 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!")
}