Variables and Constant
package main
var s string = "initial"
func main() {
var a, b int = 1, 2
const n = 5000000
f := float64(3.3)
}
For Loop
// classic initial/condition/after for loop
for j := 7; j <= 9; j++ {
fmt.Println(j)
}
// most basic for loop
i := 1
for i <= 3 {
fmt.Println(i)
i = i + 1
}
// infinite loop
for {
fmt.Println("loop")
}
If/Else
Switch
// use commas to separate multiple expression in the same case statement
switch time.Now().Weekday() {
case time.Saturday, time.Sunday:
fmt.Println("it's the weekend")
default:
fmt.Println("it's a weekday")
}
// alternate way to implement If/Else while without an expression
t := time.Now()
switch {
case t.Hour() < 12:
fmt.Println("it's before noon")
default:
fmt.Println("it's after noon")
}
Array, Slices, Maps
var a [5]int
s := make([]string, 3)
m := make(map[string]int)
Functions
Do NOT support nested functions, function overload, function default parameter
multiple return values
func vals() (int, int) {
return 3, 7
}
func main() {
a, b = vals()
_, b = vals()
}
variadic function
func sum(nums ...int) {
fmt.Printlf(nums)
}
func main() {
sum(1, 2, 3)
nums := []int{1, 2, 3, 4}
sum(nums...)
}
Clousure
Go supports anonymous functions, which can form closures.
Defer
package main
import "fmt"
func main() {
defer fmt.Println("世界")
fmt.Println('Hello')
}
Deferred function calls are pushed onto a stack. When a function returns, its deferred calls are executed in last-in-first-out order.
Panic
package main
import "fmt"
func test() {
defer func() {
if err := recover(); err != nil {
fmt.Println(err.(string))
}
}()
panic("panic errors")
}
func main() {
test()
}
Errors
Pointers, Structs, Methods, Interface
// _Interfaces_ are named collections of method
// signatures.
package main
import "fmt"
import "math"
// Here's a basic interface for geometric shapes.
type geometry interface {
area() float64
perim() float64
}
// For our example we'll implement this interface on
// `rect` and `circle` types.
type rect struct {
width, height float64
}
type circle struct {
radius float64
}
// To implement an interface in Go, we just need to
// implement all the methods in the interface. Here we
// implement `geometry` on `rect`s.
func (r rect) area() float64 {
return r.width * r.height
}
func (r rect) perim() float64 {
return 2*r.width + 2*r.height
}
// The implementation for `circle`s.
func (c circle) area() float64 {
return math.Pi * c.radius * c.radius
}
func (c circle) perim() float64 {
return 2 * math.Pi * c.radius
}
// If a variable has an interface type, then we can call
// methods that are in the named interface. Here's a
// generic `measure` function taking advantage of this
// to work on any `geometry`.
func measure(g geometry) {
fmt.Println(g)
fmt.Println(g.area())
fmt.Println(g.perim())
}
func main() {
r := rect{width: 3, height: 4}
c := circle{radius: 5}
// The `circle` and `rect` struct types both
// implement the `geometry` interface so we can use
// instances of
// these structs as arguments to `measure`.
measure(r)
measure(c)
}
Reflect
Goroutines
A goroutine is a lightweight thread of execution.
package main
import "fmt"
func f(from string) {
for i := 0; i < 3; i++ {
fmt.Println(from, ":", i)
}
func main() {
go f("args")
go func(msg string) {
fmt.Println(msg)
}("going")
var input string
fmt.Scanln(&input)
fmt.Println("done")
}
Channels
Channels are the pipes that connect concurrent goroutines. You can send values into channels from one goroutine and receive those values into another goroutine.
package main
import "fmt"
func main() {
messages := make(chan string)
go func() { messages <- "ping" }()
msg := <-messages
fmt.Println(msg)
}
messages := make(chan string, 2)
func pong(pings <-chan string, pongs chan<- string) {}
close(channel)
queue := make(chan string, 2)
queue <- "one"
queue <- "two"
close(queue)
for elem := range queue {
fmt.Println(elem)
}
Select
// Go's _select_ lets you wait on multiple channel
// operations. Combining goroutines and channels with
// select is a powerful feature of Go.
package main
import "time"
import "fmt"
func main() {
// For our example we'll select across two channels.
c1 := make(chan string)
c2 := make(chan string)
// Each channel will receive a value after some amount
// of time, to simulate e.g. blocking RPC operations
// executing in concurrent goroutines.
go func() {
time.Sleep(time.Second * 1)
c1 <- "one"
}()
go func() {
time.Sleep(time.Second * 2)
c2 <- "two"
}()
// We'll use `select` to await both of these values
// simultaneously, printing each one as it arrives.
for i := 0; i < 2; i++ {
select {
case msg1 := <-c1:
fmt.Println("received", msg1)
case msg2 := <-c2:
fmt.Println("received", msg2)
}
}
}
import
语句使用绝对路径的方式引入安装到本地的包。go get
命令安装远程仓库中托管的包├── bin
│ └── hello
├── pkg
│ └── darwin_amd64
│ └── github.com
│ └── user
│ └── stringutil.a
└── src
└── github.com
└── user
├── hello
│ ├── hello
│ └── hello.go
└── stringutil
└── reverse.go