1 基礎知識
go語言有以下特點:
編譯型語言,編譯速度快
靜態類型語言,擁有動態類型語言特點
類c語法,簡單易學
支持gc
語言層面支持併發
跨平臺編譯
2 著名的go項目:
docker:開源的應用容器引擎
kubernetes:一個開源的,用於管理雲平臺中多個主機上的容器化的應用
etcd:用於可靠地存儲集羣的配置數據的一種持久性,輕量型的,分佈式的鍵-值數據存儲系統
gogs:一款極易搭建的自助git服務
beego:一個快速開發go應用的http框架
hellow world:
package main
import "fmt"
func main() {
fmt.Println("Hello, world!")
}
3 簡單的go demo:
package main
import (
"fmt"
"time"
)
func demo(i int) {
fmt.Printf("demo%d\n", (i))
}
func main() {
num := 1
fmt.Println(num)
str := "string"
fmt.Println(str)
str = "new string"
fmt.Println(str)
var foo int
foo = 123
var bar int = 456
fmt.Println(foo, bar)
if foo == 123 {
fmt.Println("foo is 123")
}
for i := 0; i < 3; i++ {
fmt.Println(i)
}
for i := 0; i < 5; i++ {
go demo(i)
}
time.Sleep(2 * time.Second)
}
4 變量
聲明的變量必須使用(導入的包也必須使用)
多個變量賦值
:=
聲明變量
package main
import (
"fmt"
)
var N int = 100
// N := 100
// var N int
func main() {
a, b := 1, 2
fmt.Println(a, b)
var num int
num = 10
fmt.Println(num)
var test string = "test"
fmt.Println(test)
fmt.Println(N)
}
5 函數
支持多值返回,具名返回
使用
_
丟棄返回值以大寫字母開頭包級別的函數供外部訪問
func log(message string) {
}
func add(a int, b int) (ret int) {
return ret
}
func power(name string) (int, bool) {
return 1, true
}
6 結構體
不支持重載
通過組合實現繼承
沒有構造函數
可以匿名組合和具名組合
使用new創建一個結構體指針
大寫字母開頭的變量可以訪問
package main
import (
"fmt"
)
type Demo1 struct {
id int
name string
}
type Demo struct {
id int
name string
d1 Demo1
// Demo1
}
func (d *Demo) change(name string) {
d.name = name
}
func (d Demo) unchange(name string) {
d.name = name
}
func main() {
d := Demo{}
fmt.Println(d)
d.name = "demo1"
fmt.Println(d)
d.change("name2")
fmt.Println(d)
d.unchange("name3")
fmt.Println(d)
dptr := new(Demo)
// dptr := &Demo{}
fmt.Println(dptr)
dptr.name = "demo1"
fmt.Println(dptr)
dptr.change("name2")
fmt.Println(dptr)
dptr.unchange("name3")
fmt.Println(dptr)
d1 := Demo{1, "test", Demo1{}}
fmt.Println(d1)
println(d1.name)
println(d1.d1.name)
}
7 字典、數組和切片
- 字典
package main
import "fmt"
func main() {
// d := make(map[string]int)
// d := map[string]int{"1": 1, "2": 2}
d := map[string]int{}
d["1"] = 1
d["2"] = 2
d["3"] = 3
for k, v := range d {
fmt.Println(k, v)
}
v, exists := d["3"]
fmt.Println(v, exists)
}
- 數組
package main
import "fmt"
func main() {
// s := [3]int{1, 2, 3}
// s := [...]int{1, 2, 3}
var s [3]int
fmt.Println(len(s))
fmt.Println(cap(s))
s[0] = 0
s[1] = 1
s[2] = 2
// s[3] = 4
for idx, v := range s {
fmt.Println(idx, v)
}
}
- 切片
package main
import "fmt"
func main() {
// s := []int{0, 1, 2}
var s []int
s = make([]int, 3, 4)
// s := make([]int, 3, 5)
fmt.Println(len(s))
fmt.Println(cap(s))
s[0] = 0
s[1] = 1
s[2] = 2
s = append(s, 3)
for idx, v := range s {
fmt.Println(idx, v)
}
fmt.Println(s[1:3])
}
8 接口
接口只聲明,不實現
實現多態
duck-typing:如果一個對象走路像鴨子,游泳也像鴨子,叫聲也像鴨子,那麼該對象就可以被稱作爲鴨子
package main
import (
"fmt"
)
type Square struct {
a int
}
func (s *Square) Area() int {
return s.a * s.a
}
func (s *Square) Perimeter() int {
return s.a * 4
}
type Rectangle struct {
a int
b int
}
func (r *Rectangle) Area() int {
return r.a * r.b
}
func (r *Rectangle) Perimeter() int {
return (r.a + r.b) * 2
}
type Shaper interface {
Area() int
Perimeter() int
}
type AnyShape interface{}
func main() {
square := new(Square)
square.a = 2
rectangle := new(Rectangle)
rectangle.a = 2
rectangle.b = 3
fmt.Println("(1) call struct method:")
fmt.Println("square area is: ", square.Area())
fmt.Println("rectangle area is: ", rectangle.Area())
fmt.Println("\n(2) via interface:")
var shape Shaper
shape = square
fmt.Println("square area is: ", shape.Area())
shape = rectangle
fmt.Println("rectangle area is: ", shape.Area())
fmt.Println("\n(3) via empty interface:")
var anyShape AnyShape
anyShape = square
fmt.Println("square area is: ", anyShape.(*Square).Area())
anyShape = rectangle
fmt.Println("rectangle area is: ", anyShape.(*Rectangle).Area())
fmt.Println("\n(4) type assertions via switch:")
switch shape := anyShape.(type) {
case *Rectangle:
fmt.Printf("shape type is: %T\n", shape)
fmt.Println("rectangle area is: ", shape.Area())
default:
fmt.Printf("unknown type %T\n", shape)
}
fmt.Println("\n(5) type assertions via comma, ok pattern:")
anyShape = rectangle
if shape, ok := anyShape.(*Rectangle); ok {
fmt.Printf("shape type is: %T\n", shape)
fmt.Println("rectangle area is: ", shape.Area())
} else {
fmt.Printf("unknown type %T\n", shape)
}
}
9 包管理
go get: go get github.com/mattn/go-sqlite3
大寫字母開頭的變量或者函數對外可見
標準庫結構
demo pkg
10 協程
一個簡單的協程:
package main
import (
"fmt"
"sync"
"time"
)
var (
counter = 0
lock sync.Mutex
)
func main() {
for i := 0; i < 3; i++ {
go incr()
}
time.Sleep(time.Millisecond * 10)
}
func incr() {
lock.Lock()
defer lock.Unlock()
counter++
fmt.Println(counter)
}
使用通道進行協程間通信:
通道支持select
通道有類型
通道大小
go確保任意時刻只有一個協程可以訪問數據
package main
import (
"fmt"
"time"
)
func main() {
c := make(chan int)
for i := 0; i < 5; i++ {
worker := &Worker{id: i}
go worker.process(c)
}
for i := 0; i < 5; i++ {
c <- i
time.Sleep(time.Millisecond * 50)
}
}
type Worker struct {
id int
}
func (w *Worker) process(c chan int) {
for i := 0; i < 5; i++ {
data := <-c
fmt.Printf("worker %d got %d\n", w.id, data)
}
}
next
python多進程之multiprocessing
python小技巧分享