types
bool string int byte rune float complex
var variables string
var := ""
first, second := 1, 2
const f = 1 // compile time thing
if height > 4 {
} else if ...
else ...
if len := getLength(str); len < 1 {
// only scope limited len
}
func sum(x int, y int) int {
return x + y
}
func sum(x, y int) int {
return x + y
}
func sum(x, y int) (int, int) {
return x + y, y
}
func sum(x, y int) (x, y int) {
return // automatically returns x and y
}
a int
b *int
c [3]int
f func(int, int) float64
Guard clauses
return early
Structs
type car struct {
Make string
Model string
}
myCar := car{}
myCar.Model.name
anonymous struct
myCar := struct {
Make string
Model string
} {
Make: "tesla"
Model: "3"
}
type car struct {
Make string
Model string
Wheel struct {
...
}
}
embeded struct
type car struct {
make string
}
type truck struct {
car
bedSize int
}
myTruck := truck{
bedSize: 10,
car: car {
make: "tesla"
}
}
myTruck.make
struct functions
func (r rect) area() int {
return r.width * r.height
}
interfaces
implicit assgnment (unlike java)
type shape interface {
area() float64
perimeter() float64
}
type Saver interface {
Save(file string, dest string) (err int)
}
Build in
type Stringer interface {
String() string
}
type error interface {
Error() string
}
type Reader interface {
Read(p []byte) (n int, err error)
}
type Writer interface {
Write(p []byte) (n int, err error)
}
type Closer interface {
Close() error
}
Good to know
type shape struct {
...
}
func (s *shape) String() string {
...
}
func main() {
var s shape
fmt.Println(s) // can't compile, becase *s implements the interface, not s
}
Casting
c, ok := s.(circle)
// or
switch v:= num.(type) {
case int:
...
case string:
...
}
Error
val, err := throwsAnError()
type myerror struct {
someData string
}
func (e myerror) Error() {
return e.somedata
}
Loops
// for loop
for i := 1; i < 10; i++ {
...
}
// while loop
for true {
...
}
Arrays
var arr [3]arr
arr := [3]arr{1, 2, 3}
slices
b := arr[1:n]
c := arr[lowindex:]
c := arr[:higherIndex]
d := arr[:] //all
slice := make([]int, len, cap)
slice := []int{1, 2, 3}
len(slice)
cap(slice)
append to slice
slice = append(slice, one, two, three)
For of
for INDEX, ELEMENT := range SLICE {
...
}
Variadic functions
func print(str ...string) {...}
names := []string{"hello", "world"}
print(names...)
Maps
map := make(map[string]int)
map["hello"] = 1
map1 = map[string]int{
"hello": 1,
}
delete(m, key)
get := m[key]
check, ok := m[key]
Defer
calls a function until the end
user, _ = users[name]
defer delet(users, name)
Packages
packages is based on directories
// exporting functions from a pacakage (use uppercase)
func Exported() {}
func notExported() {}
inside go.mod
...
go 1.20
replace github.com/username/name v0.0.0 => ../path // replace this with a local path
require {
github.com/username/name v0.0.0
}
Go
go build package|file
go run package|file
go install package|file
go mod init github.com/username/name
go get github.com/username/name # install a package
Goroutine
go func() {
...
}
Channels
receiving from a nil channel blocks
sending to a nil channel blocks
send to a close channel panic
receiving from a close panic returns default
ch := make(chan int)
ch <- 69 // blocks
v := <-ch // blocks
close(ch)
v, ok:= <-ch
read-only
func useCh(ch chan int) { }
func readCh(ch <-chan int) { }
func writeCh(ch chan<- int) { }
Tokens
unary value => when and if it comes to the channel
token := make(chan struct{})
Buffered channels
ch := make(chan int, 100)
Range
for value := range channel {
}
Select
select {
case i, ok := <-channel:
...
case ...
default: //fires if all chanlles is waiting to a message to come
}
Mutexes
func doSmth(mutex, mymap map[string] int, key string) {
mutex.Lock()
defer mutex.Unlock()
value := mymap[key]
mymap[key] = value + 1
}
RWMutex
allows to have multiple readers
Generitcs
func getDef[T any]() T {
var zeroVal T
return zeroVal
}
Constraints
type myInterface interface {
...
}
func do[T myInterface](slice []T) {
...
}
Interface type lists
type Comparable interface {
~int | ~int8 | ~int16 | ~int32 | ~int64
}
Parametric constraints
type store[P product] interface {
Sell(P)
}