The Go language
Some notes regarding the Go language. Some topics have graduated to their own page:
Language design
Go doesn't have sets
The Go language, notoriously, does not have1 some common data structures like sets. There are two main reasons for that:
- Go does not have generics1
- Go relies on you writing your own data structures, generally
Go lacks generics, which prevent writing a ... well, generic and efficient set implementation.
Also, writing your own (non-generic) set with map
s is quite straight-forward.
The usual structure for a type T
is map[T]bool
, where the key is the element and the value is just a placeholder. For instance, for a int
set:
s := map[int]bool{1: true, 3: true}
where we can add elements:
s[1] = true // already present
s[2] = true // adds new element
Some other techniques for maps replacing sets:
Set union
set_union := map[int]bool{}
for k, _ := range set_1{
set_union[k] = true
}
for k, _ := range set_2{
set_union[k] = true
}
Set intersection
set_intersection := map[int]bool{}
for k,_ := range set_1 {
if set_2[k] {
set_intersection[k] = true
}
}
Set to array
To convert a (map) set to an array:
array := make([]int, 0)
for k := range set_1 {
array = append(array, k)
}
CI
GitHub
A potential workflow for GitHub is to use GitHub Actions for Go.
An example workflow file, .github/workflows/test.yml
, which runs go test
(see Go) and go vet
is:
on: [push, pull_request\]
name: Test
jobs:
test:
strategy:
matrix:
go-version: [1.14.x, 1.15.x]
os: [ubuntu-latest]
runs-on: ${{ matrix.os }}
steps:
- name: Install Go
uses: actions/setup-go@v2
with:
go-version: ${{ matrix.go-version }}
- name: Checkout code
uses: actions/checkout@v2
- name: Test
run: go test ./...
- name: Vet
run: go vet ./...
Containers
Minimal example
A minimal example of a Go container configuration for a web server running on port 8080
:
# Start from the latest golang base image
FROM golang:latest
# Add Maintainer Info
LABEL maintainer="Rui Vieira"
# Set the Current Working Directory inside the container
WORKDIR /app
# Copy go mod and sum files
COPY go.mod go.sum ./
# Download all dependencies. Dependencies will be cached if the go.mod and go.sum files are not changed
RUN go mod download
# Copy the source from the current directory to the Working Directory inside the container
COPY . .
# Build the Go app
RUN go build -o main .
# Expose port 8080 to the outside world
EXPOSE 8080
# Command to run the executable
CMD ["./main"]
Reference
Conversions
How to convert a string to byte array?
b := []byte("This is a string")
Collections
Sort map keys alphabetically
If a map
contains string
keys, i.e. var myMap map[string]T
, we must sort the map keys independently. For instance:
keys := make([]string, 0)
for k, _ := range myMap {
keys = append(keys, k)
}
sort.Strings(keys)
for _, k := range keys {
fmt.Println(k, myMap[k])
}
Check for element
If we consider a collection, say, []string collection
, the way to check for an element already present is, for instance:
func existsIn(needle string, haystack []string) bool {
for _, element := range haystack {
if element == needle {
return true
}
}
return false
}
Templates
Check if variable empty
In a Go template you check if a variable is empty by doing:
{{if .Items}}
<ul>
{{range .Items}}
<li>{{.Name}}</li>
{{end}}
</ul>
{{end}}
Looping over a map
Looping over the map var data map[string]bool
in a Go template:
{{range $index, $element := .}}
{{$index}}: {{$element}}
{{end}}
Processes
Executing external processes
Executing an external process and directing input and output to Stdout
and Stderr
.
cmd := exec.Command("ls", "-1ao")
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
err := cmd.Run()
if err != nil {
log.Fatalf("cmd.Run() failed with %s\\n", err)
}
Testing in Go
Place the tests in your place of choosing, but keep the package declaration. Test functions should be parameterised as (t *testing.T
and start with the prefix Test
, for instance:
package main
func TestFoo(t *testing.T) {
value := Foo(5, 5)
// ... assertions
The test files themselves must have the suffix *_test.go
.
Call the tests with go test
.