main package
package main
import "fmt" //format
func main() {
fmt.Println("Hello, 世界")
}
function
func add(x int, y int) int {
return x + y
}
func swap(x, y string) (string, string) {
return y, x
}
a, b := swap("hello", "world")
variable
var i, j int = 1, 2
var c, python, java = true, false, "no!"
k := 3
var i int // == 0
conversion
var f float64 = float64(i)
build go file
go build main.go
./main
GOOS=darwin GOARCH=amd64 go build main.go
create new module
go mod init example
install program (build + move binary)
go install example/user/hello
testing
package morestrings
import "testing"
func TestReverseRunes(t *testing.T) {
cases := []struct {
in, want string
}{
{"Hello, world", "dlrow ,olleH"},
{"Hello, 世界", "界世 ,olleH"},
{"", ""},
}
for _, c := range cases {
got := ReverseRunes(c.in)
if got != c.want {
t.Errorf("ReverseRunes(%q) == %q, want %q", c.in, got, c.want)
}
}
}
// terminal: go test
for loop
for i := 0; i < 10; i++ {
sum += i
}
conditions
if x < 0 {} else if {} else {}
switch os := runtime.GOOS; os {
case "darwin":
fmt.Println("macOS.")
default:
fmt.Printf("%s.\n", os)
}
defer
func main() {
defer fmt.Println("world") //LIFO
fmt.Println("hello")
}
pointer
var p *int
p = &i
fmt.Println(*p)
struct
type Vertex struct {
X int
Y int
}
Vertex{1, 2}
Vertex{X: 1}
v.X = 4
array
var a [10]int
primes := [6]int{2, 3, 5, 7, 11, 13}
var s []int = primes[1:4] // slice
len(s)
cap(s)
b := make([]int, 0, 5) // len(b)=0, cap(b)=5
s = append(s, 0)
for i, v := range pow {}
map
type Vertex struct {
Lat, Long float64
}
var m map[string]Vertex
func main() {
m = make(map[string]Vertex)
m["Bell Labs"] = Vertex{
40.68433, -74.39967,
}
fmt.Println(m["Bell Labs"])
}
var m = map[string]Vertex{
"Bell Labs": Vertex{
40.68433, -74.39967,
},
"Google": Vertex{
37.42202, -122.08408,
},
}
m[key] = elem
elem = m[key]
delete(m, key)
elem, ok = m[key]
closure
func adder() func(int) int {
sum := 0
return func(x int) int {
sum += x
return sum
}
}
method (function with receiver)
func (v Vertex) Abs() float64 { // call by value
return math.Sqrt(v.X*v.X + v.Y*v.Y)
}
func (v *Vertex) Scale(f float64) {} // call by reference
interface
type Abser interface {
Abs() float64
}
type MyFloat float64
func (f MyFloat) Abs() float64 {
if f < 0 {
return float64(-f)
}
return float64(f)
}
interface type assertion
t, ok := i.(T)
errors
i, err := strconv.Atoi("42")
if err != nil {
fmt.Printf("couldn't convert number: %v\n", err)
return
}
type MyError struct {
When time.Time
What string
}
func (e *MyError) Error() string {
return fmt.Sprintf("at %v, %s",
e.When, e.What)
}
func run() error {
return &MyError{
time.Now(),
"it didn't work",
}
}
func main() {
if err := run(); err != nil {
fmt.Println(err)
}
}
type parameter
func Index[T comparable](s []T, x T) int
generic type
type List[T any] struct {
next *List[T]
val T
}
goroutine
go f(x, y, z)
channel
ch := make(chan int)
ch <- v // send
v := <-ch // receive
c := make(chan int)
go sum(s[:len(s)/2], c)
go sum(s[len(s)/2:], c)
x, y := <-c, <-c
close(c)
select
func fibonacci(c, quit chan int) {
x, y := 0, 1
for {
select {
case c <- x:
x, y = y, x+y
case <-quit:
fmt.Println("quit")
return
}
}
}
mutex
package main
import (
"fmt"
"sync"
"time"
)
type SafeCounter struct {
mu sync.Mutex
v map[string]int
}
func (c *SafeCounter) Inc(key string) {
c.mu.Lock()
c.v[key]++
c.mu.Unlock()
}
func (c *SafeCounter) Value(key string) int {
c.mu.Lock()
defer c.mu.Unlock()
return c.v[key]
}
func main() {
c := SafeCounter{v: make(map[string]int)}
for i := 0; i < 1000; i++ {
go c.Inc("somekey")
}
time.Sleep(time.Second)
fmt.Println(c.Value("somekey"))
}