I am learning Go. Current latest version is 1.16 as of 2021 March. Went though A Tour of Go.
Download and Install Go or by Homebrew:
$ brew install go
-
GOPATH
defaults to$HOME/go
- These envs affects how
go build
,go get
works
Use Visual Studio Code and follow Go for Visual Studio Code.
$ go get golang.org/x/tools/cmd/godoc
Run this in your package
godoc -http :8000
You will see all Go package documents and YOURS.
Workspace is just a folder for Go to store your executables (bin
), packages (pkg
), packages from source controls (src
), defaults under $HOME/go/
.
- Workspace is where
$GOPATH
is. A workspace usually hasbin/
,pkg/
, and/src
folders. - Program is made of Packages
- Module has many Packages
- A repository has 1 module;
go.mod
declares the module path - Introduce dependency by
import
-
main.go
is the entry point. - Symbols start with capital letters are exported from packages. Use capital letter to reference a method in a imported Package.
Write Go program -> gofmt
-> go build
-> Run executable.
A go program.
// main.go
import (
"fmt"
)
package main
func main() {
fmt.Println("Hello, Go")
}
bool
string
int int8 int16 int32 int64
uint uint8 uint16 uint32 uint64 uintptr
byte // alias for uint8
rune // alias for int32
// represents a Unicode code point
float32 float64
complex64 complex128
u
means unsigned.
When it is over the range, it circles back. uint8
0-255, 256 -> 0.
float32
uses less memory but if you need high precision, use float64
Init values (or zero value):
package main
import (
"fmt"
)
func main() {
var i int
var f float64
var b bool
var s string
fmt.Printf("%v %v %v %q\n", i, f, b, s)
}
// => 0 0 false ""
package main
import (
"fmt"
"math"
)
func main() {
var x, y int = 3, 4
var f float64 = math.Sqrt(float64(x*x + y*y))
var z uint = uint(f)
fmt.Println(x, y, z)
}
"Hello, Go"
Newline => "\n"
String literal => `\n` // (multiline is ok for `...` string)
// The following are the same .Codepoint of 128518 is 😆.
emoji := 128518
easier := '😆'
func(x int, y int)
func(x, y int)
func fib(n int16) int64 {
if n == 0 {
return 0
} else if n == 1 {
return 1
} else {
return fib(n-1) + fib(n-2)
}
}
Return values can be named
func split(sum int) (x, y int) {
x = sum * 2
y = sum - x
return
}
split(10)
package main
import "fmt"
func main() {
for i := 10; i > 0; i-- {
fmt.Println(i)
}
}
Go has no while, do, until to implement "while loop". Here is how to make a while loop using for
:
// Loop forever
for {
}
Condition not surrounded by parens:
if num := rand.Intn(3); num == 0 {
fmt.Println("0")
} else if num == 1 {
fmt.Println("1")
} else {
fmt.Println("2")
}
can use break
to exit early.
switch num := rand.Intn(10); num {
case 0:
fmt.Println("0")
case 1:
fmt.Println("1")
case 2:
fmt.Println("2")
default:
fmt.Println("> 2", num)
}
Delay execution of a function. Use in situations like Unlock Mutex, close reading a stream of content.
var c, python, java bool
var i, j int = 1, 2
const hoursPerDay = 24 // this is a constant
var identifier type = value
var weight float64 = 55.5
var checkedOut bool = false
:=
is shorthand for var x = ...
var identifier type = value
type := value
-
&
before a variable to get variable's memory address. -
*
before a variable to resolves a memory address.
package juanito
const firstName = "Juanito"
func main() {
return juanito.firstName
}
Constant cannot be declared by shorthand (:=
).
var age = 30
// shorthand
age := 30
import("fmt")
fmt.Print
fmt.Println
Build and Run:
go build file.log
./file
package main
import (
"fmt"
"math/rand"
)
func main() {
fmt.Println("My favorite number is", rand.Intn(10))
}
Pointer is memory address of value.
var p *int
*int
is a pointer to a int
value.
age := 42
pointer_age = &age
Written in Go itself. Awesome.
-
go.mod
:module github.com/juanitofatas/mygo/v2
-
require
:require github.com/juanitofatas/mygo/v2 v2.0.0
-
import
:import "github.com/juanitofatas/mygo/v2/mypkg"
-
replace
:replace github.com/original/proj github.com/juanitofatas/forked-proj v0.1.2.20200909123456-0f7232a2bf7e
-
exclude
: can
When your Go repository is still v0 or v1, the version suffix can be neglected for practical use (v0 does not need to care version compatibility, v1 is common so omit).
version pattern vMAJOR.MINOR.PATCH.yyyymmddhhmmss-abcdefabcdef
https://github.com/golang/go/wiki/Modules#gomod
// go.mod
module github.com/juanitofatas/lib-go/v2
go 1.15.2
require (
github.com/stretchr/testify v1.6.1
)
go.sum
is not a lockfile. go.sum
is a record to make sure modules not being modified by checking its checksum.
-
go list -m all
— list all dependencies -
go list -u -m all
— list all upgradable dependencies -
go get -u
— upgrade all dependencies to latest -
go get -u=patch
— upgrade all dependencies to latest patch -
go mod tidy
— remove unused dependency -
go clean -modcache
— to remove all modules
- Read Go Wiki
- Read Go Documentation
- Trending Go projects on GitHub
- There is a proposal called Go Generics to solve ??? problems.
- Go Style Guide (Sort of).
- Dependencies Management: Go Modules.
- Minimal Version Selection (Go chose oldest allowed version; compares to other community always uses latest allowed version)
- Hard to google things "go get", "go import"
- Built-in Testing library but verbose. Many people use Testify.