Features
- GC
- Concurrency
- powerful STD Lib
- Binary
- Cross platform
Hello World
1
2
3
4
5
6
7
8
// The entry point for the application is the main function in the main package
package main
import "fmt"
func main() {
fmt.Printf("hello, world\n")
}
1
2
go build hello.go
./hello
CLI
- env
- work
ENV
1
export GOPATH=$HOME/go
GOOS
and GOARCH
for cross-platform compiling
Package
Exported names
In Go
, a name is exported if it begins with a capital letter. For example, Pizza
is an exported name, as is Pi
, which is exported from the math package.
pizza
and pi
do not start with a capital letter, so they are not exported.
Init
Module
1
go mod tidy
Functions
1
2
3
func add(x int, y int) int {
return x + y
}
Multiple Return Values
1
2
3
4
5
func f1() (int, int) {
return 3, 7
}
a, b := f1()
Variables
The var
statement declares a list of variables; as in function argument lists, the type is last.
1
2
3
var c, python, java bool
var i, j int = 1, 2
Inside a function, the :=
short assignment statement can be used in place of a var declaration with implicit type.
Outside a function, every statement begins with a keyword (var
, func
, and so on) and so the :=
construct is not available.
Basic types
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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
Constants
1
const World = "World"
iota
Loop
Go has only one looping construct, the for
loop.
The basic for loop has three components separated by semicolons:
- the init statement: executed before the first iteration
- the condition expression: evaluated before every iteration
- the post statement: executed at the end of every iteration
1
2
3
4
5
6
7
8
9
10
11
package main
import "fmt"
func main() {
sum := 0
for i := 0; i < 10; i++ {
sum += i
}
fmt.Println(sum)
}
If
1
2
3
4
5
if v := math.Pow(x, n); v < lim {
return v
} else {
return 1
}
Note that you don’t need parentheses around conditions in Go, but the braces are required.
Switch
A switch statement is a shorter way to write a sequence of if - else
statements.
Go’s switch is like the one in C
, C++
, Java
, JavaScript
, and PHP
, except that Go
only runs the selected case, not all the cases that follow.
1
2
3
4
5
6
7
8
9
10
11
12
func main() {
i := 2
fmt.Print("Write ", i, " as ")
switch i {
case 1:
fmt.Println("one")
case 2:
fmt.Println("two")
case 3:
fmt.Println("three")
}
}
Defer
A defer statement defers the execution of a function until the surrounding function returns.
Deferred function calls are pushed onto a stack.
Pointer
Struct
Pointer to structs
To access the field X
of a struct
when we have the struct pointer p
we could write (*p).X
. However, that notation is cumbersome, so the language permits us instead to write just p.X
, without the explicit dereference.
1
2
3
4
5
6
var (
v1 = Vertex{1, 2} // has type Vertex
v2 = Vertex{X: 1} // Y:0 is implicit
v3 = Vertex{} // X:0 and Y:0
p = &Vertex{1, 2} // has type *Vertex
)
Array
1
2
3
q := []int{2, 3, 5, 7, 11, 13}
arr := [5]string{1:"b", 3:"d"}
The capacity of a slice is the number of elements in the underlying array, counting from the first element in the slice.
The zero value of a slice is nil
.
Slice
1
2
3
s := make([]string, 3)
q := []int{2, 3, 5, 7, 11, 13}
Map
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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"])
// check if exist
value,ok := m["Be"]
if ok {
fmt.Println(value)
}
}
Map literals
1
2
3
4
5
6
7
8
var m = map[string]Vertex{
"Bell Labs": Vertex{
40.68433, -74.39967,
},
"Google": Vertex{
37.42202, -122.08408,
},
}
Delete an element:
1
delete(m, key)
Test that a key is present with a two-value assignment:
If key is in m, ok is true
. If not, ok is false
.
1
2
v, ok := m["Answer"]
fmt.Println("The value:", v, "Present?", ok)
Method
Go does not have classes. However, you can define methods on types.
A method is a function with a special receiver argument.
The receiver appears in its own argument list between the func keyword and the method name.
1
2
3
4
5
6
7
8
9
10
11
12
13
type Vertex struct {
X, Y float64
}
func (v Vertex) Abs() float64 {
return math.Sqrt(v.X*v.X + v.Y*v.Y)
}
func main() {
v := Vertex{3, 4}
fmt.Println(v.Abs())
}
Remember: a method is just a function with a receiver argument.
You can declare a method on non-struct types, too.
Interface
1
2
3
type Abser interface {
Abs() float64
}
There is no explicit declaration of intent, no "implements"
keyword.
1
t := i.(T)
This statement asserts that the interface value i
holds the concrete type T
and assigns the underlying T
value to the variable t.
Type Switch
1
2
3
4
5
6
7
8
switch v := i.(type) {
case T:
// here v has type T
case S:
// here v has type S
default:
// no match; here v has the same type as i
}
The declaration in a type switch has the same syntax as a type assertion i.(T)
, but the specific type T
is replaced with the keyword type
.
One of the most ubiquitous interfaces is Stringer defined by the fmt
package.
1
2
3
type Stringer interface {
String() string
}
Error
Panic
Reflect
Test
Unit Test
1
go test test_dir
Coverage
Benchmark
Lint
golangci-lint
Gin
RPC
Tips
Go 语言中,参数的传递为值传递
map, chan 均为指针类型
make
函数用于 slice
, map
, chan
的初始化
slice
自动扩容时,会创建一个新数组,再把原来的元素拷贝过去。