GO語言基礎
認識并安裝GO語言開發環境
Go語言簡介
Go語言是谷歌2009年發布的第二款開源編程語言
go語言專門針對多處理器系統應用程序的編程進行了優化,使用Go編譯的程序可以媲美C或C++代碼的速度,而且更加安全,支持并行進程
Go語言特點
簡潔、快速、安全
并行、有趣、開源
內存管理,數組安全,編譯迅速
Go語言開發的應用
docker
Codis(豆瓣開發的大部分使用go語言)
Glow類似于hadoop
cockroach
一些見解
Java語言的份額繼續下滑,并最終被C和Go語言超越;
C語言將長居編程榜第二的位置,并有望在Go取代java前重獲語言榜第一的寶座
Go語言最終會取代java,居于編程榜之首
Go語言環境搭建
go源碼安裝
go標準包安裝
第三方工具安裝 比如GVM
-
go語言開發工具
LiteIDE
IDE
eclipese、sublime
GO語言基礎知識
第一個Go應用HelloWord
- <pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="" cid="n57" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 1.125rem; display: block; break-inside: avoid; text-align: left; white-space: normal; background: inherit; position: relative !important; color: rgb(122, 122, 122); padding: 0.5rem 1.125em; margin-bottom: 0.88em; border: 1px solid rgb(122, 122, 122); margin-top: 0px; line-height: 1.5rem; width: inherit;">package main
import "fmt"
func main(){
//go語言不強制加分號
fmt.Print("Hello word")
}
//cmd輸入 go run hello.go輸出結果</pre>
配置
-
go語言依賴一個重要得環境變量:$GOPATH(不是安裝目錄)
使用go get github.com/astaxie/beego命令下載框架失敗,是因為未配置gopath
set GOPATH=e:/go_path:設置gopath路徑
echo %GOPATH%:查看gopath路徑
-
gopath得作用
下載第三方代碼
包管理與引用
gopath多個包調用代碼練習
Go語言常用關鍵字
-
break default func interface select case defer go map struct chan else goto package switch const fallthrough if range type continue for import return var
package main下得main()函數是go語言得入口
-
var:關鍵字是go最基本得定義變量的方式,與C語言不同的是Go把變量類型放在變量名后面
- 例:var x int
Go語言開發工具liteide
創建應用編譯
y:="hello" //簡短聲明的使用,可定義多個
-
代碼:
- <pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="" cid="n100" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 1.125rem; display: block; break-inside: avoid; text-align: left; white-space: normal; background: inherit; position: relative !important; color: rgb(122, 122, 122); padding: 0.5rem 1.125em; margin-bottom: 0.88em; border: 1px solid rgb(122, 122, 122); margin-top: 0px; line-height: 1.5rem; width: inherit;">package main
?
import "fmt"
?
func main() {
var x int
x = 1
//這種用法須在函數體內
y, z := "go demo", 2
fmt.Printf("%d %s %d", x, y, z)
}
?</pre>
- <pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="" cid="n100" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 1.125rem; display: block; break-inside: avoid; text-align: left; white-space: normal; background: inherit; position: relative !important; color: rgb(122, 122, 122); padding: 0.5rem 1.125em; margin-bottom: 0.88em; border: 1px solid rgb(122, 122, 122); margin-top: 0px; line-height: 1.5rem; width: inherit;">package main
go語言數據類型
bool
runne
int8、int16、int32、int64
byte
unit8、unit16、unit32、unit64
flot32、float64
complex64、complex128
string
array slice
map
其它基礎
數組的定義
其它數據類型的使用
s:=make([]int,10,20)//slice動態數組對象
-
map:student:=make(map[string]int)
- make用于內建類型(map、slice、channel)的內存分配
-
流程控制語句
if語句
-
for
- <pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="" cid="n145" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 1.125rem; display: block; break-inside: avoid; text-align: left; white-space: normal; background: inherit; position: relative !important; color: rgb(122, 122, 122); padding: 0.5rem 1.125em; margin-bottom: 0.88em; border: 1px solid rgb(122, 122, 122); margin-top: 0px; line-height: 1.5rem; width: inherit;">func main() {
sum := 0
x := 1
for x <= 100 {
sum += x
x++
}
fmt.Print(sum)
}</pre>
- <pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="" cid="n145" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 1.125rem; display: block; break-inside: avoid; text-align: left; white-space: normal; background: inherit; position: relative !important; color: rgb(122, 122, 122); padding: 0.5rem 1.125em; margin-bottom: 0.88em; border: 1px solid rgb(122, 122, 122); margin-top: 0px; line-height: 1.5rem; width: inherit;">func main() {
-
switch
- <pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="" cid="n150" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 1.125rem; display: block; break-inside: avoid; text-align: left; white-space: normal; background: inherit; position: relative !important; color: rgb(122, 122, 122); padding: 0.5rem 1.125em; margin-bottom: 0.88em; border: 1px solid rgb(122, 122, 122); margin-top: 0px; line-height: 1.5rem; width: inherit;">x:=1
switch x{
case 1:
fmt.Print("demo1")
//GO默認添加了break
break
case 2:
//繼續需要添加
fallthrough
case 3:
fmt.Print("demo2")
break
default 3:
fmt.Print("demo3")
}</pre>
- <pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="" cid="n150" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 1.125rem; display: block; break-inside: avoid; text-align: left; white-space: normal; background: inherit; position: relative !important; color: rgb(122, 122, 122); padding: 0.5rem 1.125em; margin-bottom: 0.88em; border: 1px solid rgb(122, 122, 122); margin-top: 0px; line-height: 1.5rem; width: inherit;">x:=1
-
for循環
- <pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="" cid="n155" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 1.125rem; display: block; break-inside: avoid; text-align: left; white-space: normal; background: inherit; position: relative !important; color: rgb(122, 122, 122); padding: 0.5rem 1.125em; margin-bottom: 0.88em; border: 1px solid rgb(122, 122, 122); margin-top: 0px; line-height: 1.5rem; width: inherit;">x := [5]int{1, 2, 3, 4, 5}
for i, v := range x {
fmt.Println(i, v)
}
x := make(map[string]int)
x["zhangsan"] = 78
x["lisi"] = 90
x["wangwu"] = 100
for i, v := range x {
fmt.Println(i, v)
}
x := "zhangsan"
for _, v := range x {
fmt.Printf("%c\n", v)
}</pre>
- <pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="" cid="n155" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 1.125rem; display: block; break-inside: avoid; text-align: left; white-space: normal; background: inherit; position: relative !important; color: rgb(122, 122, 122); padding: 0.5rem 1.125em; margin-bottom: 0.88em; border: 1px solid rgb(122, 122, 122); margin-top: 0px; line-height: 1.5rem; width: inherit;">x := [5]int{1, 2, 3, 4, 5}
-
Go語言函數
<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="" cid="n160" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 1.125rem; display: block; break-inside: avoid; text-align: left; white-space: normal; background: inherit; position: relative !important; color: rgb(122, 122, 122); padding: 0.5rem 1.125em; margin-bottom: 0.88em; border: 1px solid rgb(122, 122, 122); margin-top: 0px; line-height: 1.5rem; width: inherit;">func funcName(input1 type1,input2 type2)(output1 type1,output2 type2){
//邏輯處理代碼
//返回多個值
return value1,value2
}
package main
?
import "fmt"
?
func swap(a int, b int) (int, n int) {
return b, a
}
func main() {
a := 1
b := 2
a, b = swap(a, b)
fmt.Printf("%d %d", a, b)
}
//匿名函數
f:=func(x,y int)int{
return x+y
}
fmt.Println(f(2,3))</pre>go語言中指針的概念
-
defer關鍵詞使執行順序倒著走,退出或資源關閉時使用
- <pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="" cid="n167" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 1.125rem; display: block; break-inside: avoid; text-align: left; white-space: normal; background: inherit; position: relative !important; color: rgb(122, 122, 122); padding: 0.5rem 1.125em; margin-bottom: 0.88em; border: 1px solid rgb(122, 122, 122); margin-top: 0px; line-height: 1.5rem; width: inherit;">defer func() {
fmt.Println("After defer")
}()
fmt.Println("befor defer")
//defer語句遇到異常繼續執行</pre>
- <pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="" cid="n167" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 1.125rem; display: block; break-inside: avoid; text-align: left; white-space: normal; background: inherit; position: relative !important; color: rgb(122, 122, 122); padding: 0.5rem 1.125em; margin-bottom: 0.88em; border: 1px solid rgb(122, 122, 122); margin-top: 0px; line-height: 1.5rem; width: inherit;">defer func() {
-
Go語言結構struct
- <pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="" cid="n172" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 1.125rem; display: block; break-inside: avoid; text-align: left; white-space: normal; background: inherit; position: relative !important; color: rgb(122, 122, 122); padding: 0.5rem 1.125em; margin-bottom: 0.88em; border: 1px solid rgb(122, 122, 122); margin-top: 0px; line-height: 1.5rem; width: inherit;">package main
import "fmt"
type Person struct {
name string
age int
}
type Student struct{
Person//匿名字段,使用和類包含類似
speciality string
}
func main() {
person := Person{"zhangsan", 25}
// person2 :=Person{age:25,name:"wangwu"}//指定字段賦值
fmt.Printf("%v", person)
}</pre>
- <pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="" cid="n172" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 1.125rem; display: block; break-inside: avoid; text-align: left; white-space: normal; background: inherit; position: relative !important; color: rgb(122, 122, 122); padding: 0.5rem 1.125em; margin-bottom: 0.88em; border: 1px solid rgb(122, 122, 122); margin-top: 0px; line-height: 1.5rem; width: inherit;">package main
GO語言面向對象
類的定義與使用
-
簡單定義使用
- <pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="" cid="n180" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 1.125rem; display: block; break-inside: avoid; text-align: left; white-space: normal; background: inherit; position: relative !important; color: rgb(122, 122, 122); padding: 0.5rem 1.125em; margin-bottom: 0.88em; border: 1px solid rgb(122, 122, 122); margin-top: 0px; line-height: 1.5rem; width: inherit;">package main
?
import "fmt"
?
type Integer struct {
value int
}
?
func (a Integer) compare(b Integer) bool {
return a.value < b.value
}
func main() {
// var a int =1
// var b int =2
a := Integer{1}
b := Integer{2}
fmt.Printf("%v", a.compare(b))
}
?</pre>
- <pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="" cid="n180" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 1.125rem; display: block; break-inside: avoid; text-align: left; white-space: normal; background: inherit; position: relative !important; color: rgb(122, 122, 122); padding: 0.5rem 1.125em; margin-bottom: 0.88em; border: 1px solid rgb(122, 122, 122); margin-top: 0px; line-height: 1.5rem; width: inherit;">package main
-
go中類的初始化
<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="" cid="n185" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 1.125rem; display: block; break-inside: avoid; text-align: left; white-space: normal; background: inherit; position: relative !important; color: rgb(122, 122, 122); padding: 0.5rem 1.125em; margin-bottom: 0.88em; border: 1px solid rgb(122, 122, 122); margin-top: 0px; line-height: 1.5rem; width: inherit;">point:=new(Point)
point:=&Point{}
point:=&Point{x:100,y:100}
point:=Point{}</pre>-
定義與使用示例
- <pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="" cid="n190" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 1.125rem; display: block; break-inside: avoid; text-align: left; white-space: normal; background: inherit; position: relative !important; color: rgb(122, 122, 122); padding: 0.5rem 1.125em; margin-bottom: 0.88em; border: 1px solid rgb(122, 122, 122); margin-top: 0px; line-height: 1.5rem; width: inherit;">package main
import "fmt"
type Point struct {
px float32
py float32
}
func (point *Point) setxy(px, py float32) {
point.px = px
point.py = py
}
func (point *Point) getxy() (float32, float32) {
return point.px, point.py
}
func main() {
point := new(Point)
point.setxy(1.24, 4.25)
px, py := point.getxy()
fmt.Print(px, py)
}</pre>
- <pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="" cid="n190" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 1.125rem; display: block; break-inside: avoid; text-align: left; white-space: normal; background: inherit; position: relative !important; color: rgb(122, 122, 122); padding: 0.5rem 1.125em; margin-bottom: 0.88em; border: 1px solid rgb(122, 122, 122); margin-top: 0px; line-height: 1.5rem; width: inherit;">package main
類的繼承與使用
<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="" cid="n194" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 1.125rem; display: block; break-inside: avoid; text-align: left; white-space: normal; background: inherit; position: relative !important; color: rgb(122, 122, 122); padding: 0.5rem 1.125em; margin-bottom: 0.88em; border: 1px solid rgb(122, 122, 122); margin-top: 0px; line-height: 1.5rem; width: inherit;">package main
?
import "fmt"
?
type Person struct {
name string
age int
}
?
func (person Person) getNameAndAge() (string, int) {
return person.name, person.age
}
?
type Student struct {
Person
speciality string
}
?
func (student Student) getSpeciality() string {
return student.speciality
}
func main() {
student := new(Student)
student.name = "zhangsan"
student.age = 26
name, age := student.getNameAndAge()
fmt.Println(name, age)
}</pre>-
Go語言接口
-
在go語言中,一個類只需要實現了接口要求的所有函數,我們就說這個類實現了該接口
- <pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="" cid="n202" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 1.125rem; display: block; break-inside: avoid; text-align: left; white-space: normal; background: inherit; position: relative !important; color: rgb(122, 122, 122); padding: 0.5rem 1.125em; margin-bottom: 0.88em; border: 1px solid rgb(122, 122, 122); margin-top: 0px; line-height: 1.5rem; width: inherit;">package main
?
import "fmt"
//非侵入式接口
type Animal interface {
Fly()
Run()
}
type Animal2 interface {
Fly()
}
type Bird struct {
}
func (bird Bird) Fly() {
fmt.Println("bird is flying")
}
func (bird Bird) Run() {
fmt.Println("bird is Run")
}
func main() {
var animal Animal
var animal2 Animal2
bird := new(Bird)
animal = bird
animal2=bird
animal2.FLy()
animal2=animal//在GO中可以接口賦值
animal.Fly()
animal.Run()
}</pre>
- <pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="" cid="n202" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 1.125rem; display: block; break-inside: avoid; text-align: left; white-space: normal; background: inherit; position: relative !important; color: rgb(122, 122, 122); padding: 0.5rem 1.125em; margin-bottom: 0.88em; border: 1px solid rgb(122, 122, 122); margin-top: 0px; line-height: 1.5rem; width: inherit;">package main
-
在Go語言中空間口類似泛型
- <pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="" cid="n207" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 1.125rem; display: block; break-inside: avoid; text-align: left; white-space: normal; background: inherit; position: relative !important; color: rgb(122, 122, 122); padding: 0.5rem 1.125em; margin-bottom: 0.88em; border: 1px solid rgb(122, 122, 122); margin-top: 0px; line-height: 1.5rem; width: inherit;">var v1=interface{}
v1=6.78
fmt.Print(v1)
//類型查詢,看接口接收的什么類型
if v, ok := v1.(float64); ok {
fmt.Println(v, ok)
}</pre>
- <pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="" cid="n207" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 1.125rem; display: block; break-inside: avoid; text-align: left; white-space: normal; background: inherit; position: relative !important; color: rgb(122, 122, 122); padding: 0.5rem 1.125em; margin-bottom: 0.88em; border: 1px solid rgb(122, 122, 122); margin-top: 0px; line-height: 1.5rem; width: inherit;">var v1=interface{}
-
GO語言進階
GO語言并發編程
Go語言并發編程之協程
與傳統的系統級線程相比,協程的大優勢在于其"輕量級",可以輕松創建上百萬個而不會導致系統資源衰竭,而線程和進程通常多也不能超過1萬個,這也是協程也叫輕量級線程的原因.
-
go對協程的實現:go+函數名:啟動一個協程執行函數體
- <pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="" cid="n218" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 1.125rem; display: block; break-inside: avoid; text-align: left; white-space: normal; background: inherit; position: relative !important; color: rgb(122, 122, 122); padding: 0.5rem 1.125em; margin-bottom: 0.88em; border: 1px solid rgb(122, 122, 122); margin-top: 0px; line-height: 1.5rem; width: inherit;">package main
import (
"fmt"
"time"
)
func test_Routine() {
fmt.Println("This is one routine!")
}
func main() {
go test_Routine()
time.Sleep(1)
}</pre>
- <pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="" cid="n218" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 1.125rem; display: block; break-inside: avoid; text-align: left; white-space: normal; background: inherit; position: relative !important; color: rgb(122, 122, 122); padding: 0.5rem 1.125em; margin-bottom: 0.88em; border: 1px solid rgb(122, 122, 122); margin-top: 0px; line-height: 1.5rem; width: inherit;">package main
-
Go并發編程之channel
-
Channel:Go語言在語言級別提供的goroutine間的通訊方式
-
聲明方式:var chanName chan ElementType
- <pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="" cid="n229" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 1.125rem; display: block; break-inside: avoid; text-align: left; white-space: normal; background: inherit; position: relative !important; color: rgb(122, 122, 122); padding: 0.5rem 1.125em; margin-bottom: 0.88em; border: 1px solid rgb(122, 122, 122); margin-top: 0px; line-height: 1.5rem; width: inherit;">package main
?
import (
"fmt"
"strconv"
)
?
func Add(x, y int, quit chan int) {
z := x + y
fmt.Println(z)
quit <- 1
}
func Read(ch chan int) {
value := <-ch
fmt.Println("value:" + strconv.Itoa(value))
}
func Write(ch chan int) {
// ch < -10
}
func main() {
chs := make([]chan int, 10)
for i := 0; i < 10; i++ {
chs[i] = make(chan int)
go Add(i, i, chs[i])
}
for _, v := range chs {
<-v
}
}</pre>
- <pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="" cid="n229" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 1.125rem; display: block; break-inside: avoid; text-align: left; white-space: normal; background: inherit; position: relative !important; color: rgb(122, 122, 122); padding: 0.5rem 1.125em; margin-bottom: 0.88em; border: 1px solid rgb(122, 122, 122); margin-top: 0px; line-height: 1.5rem; width: inherit;">package main
-
-
緩存channel
-
<pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="" cid="n235" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 1.125rem; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background: inherit; position: relative !important; color: rgb(122, 122, 122); padding: 0.5rem 1.125em; margin-bottom: 0.88em; border: 1px solid rgb(122, 122, 122); margin-top: 0px; line-height: 1.5rem; width: inherit;">package main
import (
"fmt"
"time"
)var ch chan int
func test_channel() {
// ch := make(chan int)
ch <- 1
fmt.Println("come to end goroutline 1")
}
func main() {
ch = make(chan int, 2) //值是1和值是0的適合輸出執行順序不同
go test_channel()
time.Sleep(2 * time.Second)
fmt.Println("running end!")
<-ch
time.Sleep(time.Second)
}
</pre>
-
-
select
是linux很早就引入的函數,用來實現非阻塞的一種方式
-
go語言提供語言級別支持slelect關鍵字,用于處理異步IO問題
- <pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="" cid="n245" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 1.125rem; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background: inherit; position: relative !important; color: rgb(122, 122, 122); padding: 0.5rem 1.125em; margin-bottom: 0.88em; border: 1px solid rgb(122, 122, 122); margin-top: 0px; line-height: 1.5rem; width: inherit;">select{
case <-chan1://如果chan1成功讀取到數據,則進行該case處理語句
case chan2 <-1://如果成功向chan2寫入數據,則進行該case處理
default: //如果上面都沒有成功,則進入default處理流程
}
</pre>
- <pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="" cid="n245" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 1.125rem; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background: inherit; position: relative !important; color: rgb(122, 122, 122); padding: 0.5rem 1.125em; margin-bottom: 0.88em; border: 1px solid rgb(122, 122, 122); margin-top: 0px; line-height: 1.5rem; width: inherit;">select{
-
select 三個代碼示例
-
示例1
<pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="" cid="n251" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 1.125rem; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background: inherit; position: relative !important; color: rgb(122, 122, 122); padding: 0.5rem 1.125em; margin-bottom: 0.88em; border: 1px solid rgb(122, 122, 122); line-height: 1.5rem; width: inherit;">package main
import (
"fmt"
"time"
)func main() {
ch := make(chan int)
go func(ch chan int) {
ch <- 1
}(ch)
// time.Sleep(2)//加這一句執行結果不同
select {
case <-ch:
fmt.Print("come to read ch!")
default:
fmt.Print("come to default!")
}
}
</pre> -
示例2
<pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="" cid="n254" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 1.125rem; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background: inherit; position: relative !important; color: rgb(122, 122, 122); padding: 0.5rem 1.125em; margin-bottom: 0.88em; border: 1px solid rgb(122, 122, 122); line-height: 1.5rem; width: inherit;">package main
//超時控制的經典實現
import (
"fmt"
"time"
)func main() {
ch := make(chan int)
timeout := make(chan int, 1)
go func() {
time.Sleep(time.Second)
timeout <- 1
}()
select {
case <-ch:
fmt.Println("come to read ch!")
case <-timeout:
fmt.Println("come to timeout")
}
fmt.Print("end of code!")
}
</pre> -
示例3
<pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="" cid="n257" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 1.125rem; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background: inherit; position: relative !important; color: rgb(122, 122, 122); padding: 0.5rem 1.125em; margin-bottom: 0.88em; border: 1px solid rgb(122, 122, 122); line-height: 1.5rem; width: inherit;">package main
//超時控制的經典實現
import (
"fmt"
"time"
)func main() {
ch := make(chan int)
select {
case <-ch:
fmt.Println("come to read ch!")
case <-time.After(time.Second):
fmt.Println("come to timeout")
}
fmt.Print("end of code!")
}
</pre>
-
-
-
深入Go協程編程
-
協程與線程質的不同
協程任務的業務代碼主動要求切換,即主動讓出執行權
發生了IO,導致執行阻塞
-
線程與協程代碼對比(線程幾百個就卡,協程十萬個都不算多)
-
Java線程
<pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="" cid="n273" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 1.125rem; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background: inherit; position: relative !important; color: rgb(122, 122, 122); padding: 0.5rem 1.125em; margin-bottom: 0.88em; border: 1px solid rgb(122, 122, 122); line-height: 1.5rem; width: inherit;">public class MyThread{
public static void main(String[] args){
new Thread(new Test_thread()).start();
new Thread(new Test_thread2()).start()
}
}
class Test_thread implements Runnable{
public void run(){
for(int i=0;i<100;i++){
System.out.println("thread 1:"+i)
}
}
}
class Test_thread2 implements Runnable{
public void run(){
for(int i=100;i<200;i++){
System.out.println("thread 2:+i);
}
}
}
</pre> -
Go協程
<pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="" cid="n276" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 1.125rem; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background: inherit; position: relative !important; color: rgb(122, 122, 122); padding: 0.5rem 1.125em; margin-bottom: 0.88em; border: 1px solid rgb(122, 122, 122); line-height: 1.5rem; width: inherit;">package main
import (
"fmt"
// "runtime"
"strconv"
"time"
)
func main() {
//協程1
go func() {
for i := 1; i < 100; i++ {
if i == 10 {
// runtime.Gosched() //主動要求切換CPU
<-ch //遇到阻塞主動讓出,否則一直執行下去
}
fmt.Println("routine 1:" + strconv.Itoa(i))
}
}()
//協程2
go func() {
for i := 100; i < 200; i++ {
fmt.Println("routine 2:" + strconv.Itoa(i))
}
}()
time.Sleep(time.Second)
}
</pre>
-
-
GO語言JSON與MD5
Go語言的JSON
-
使用的庫
Go語言內置的encoding/json標準庫:性能不太好
github.com/pquerna/ffjson/ffjson
-
json使用代碼
<pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="" cid="n289" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 1.125rem; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background: inherit; position: relative !important; color: rgb(122, 122, 122); padding: 0.5rem 1.125em; margin-bottom: 0.88em; border: 1px solid rgb(122, 122, 122); line-height: 1.5rem; width: inherit;">package main
import (
"encoding/json"
"fmt"
)type Student struct {
Name string //外部要引用要首字母大寫
Age int
}func main() {
//對數組類型的json編碼
x := [5]int{1, 2, 3, 4, 5}
s, err := json.Marshal(x)
if err != nil {
panic(err)
}
fmt.Println(string(s))
//對map類型進行json編碼
m := make(map[string]float64)
m["zhangsan"] = 100.4
s2, err2 := json.Marshal(m)
if err2 != nil {
panic(err2)
}
fmt.Println(string(s2))
//對對象進行json編碼
student := Student{"zhangsan", 26}
s3, err3 := json.Marshal(student)
if err3 != nil {
panic(s3)
}
fmt.Println(string(s3))
//對s3進行解碼
var s4 interface{}
json.Unmarshal([]byte(s3), &s4)
fmt.Printf("%v", s4)
}
</pre> -
md5使用
<pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="" cid="n292" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 1.125rem; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background: inherit; position: relative !important; color: rgb(122, 122, 122); padding: 0.5rem 1.125em; margin-bottom: 0.88em; border: 1px solid rgb(122, 122, 122); line-height: 1.5rem; width: inherit;">package main
import (
"crypto/md5"
"fmt"
)func main() {
Md5Inst := md5.New()
Md5Inst.Write([]byte("zhangsan"))
Result := Md5Inst.Sum([]byte(""))
fmt.Printf("%x\n\n", Result)
}
</pre>
GO語言HTTP
go語言標準庫內建提供了net/http包
-
處理http請求:使用net/http包提供的http.ListenAndServer()方法,可以在指定的地址進行監聽,開啟一個HTTP.服務端該方法的原型如下:func ListenAndServe(addr string,hander Handler)error
- 該方法用于在指定的TCP網絡地址addr進行監聽,然后調用服務端處理程序來處理傳入的鏈接請求.該方法有兩個參數:第一個參數addr即監聽地址;第二個服務表示服務端處理程序,通常為空,這意味著服務端調用http.DefaultServeMux進行處理,而服務端編寫的業務邏輯處理程序http.Handle()或http.HandleFunc()默認注入http.DefaultServeMux中
-
處理https請求
func ListenAndServeTLS(addr string,certFile string,keyFile string,handler Handler) error
-
http.HandleFunc()方法接受兩個參數
第一個參數是http請求的目標路徑"/hello",該參數值可以是字符串,也可以是字符串形式的正則表達式,第二個參數指定具體的回調方法,比如helloHandler
當我們的程序運行起來后,訪問-http://localhost:8080/hello,程序就會去調用hellloHandler()方法中的業務邏輯程序
-
http中get和postdaima
-
<pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="" cid="n318" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 1.125rem; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background: inherit; position: relative !important; color: rgb(122, 122, 122); padding: 0.5rem 1.125em; margin-bottom: 0.88em; border: 1px solid rgb(122, 122, 122); margin-top: 0px; line-height: 1.5rem; width: inherit;">//get代碼
package mainimport (
"fmt"
"io/ioutil"
"net/http"
)func main() {
resp, err := http.Get("http://www.baidu.com")
if err != nil {
panic(err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
fmt.Println(string(body))
}
//post代碼
package mainimport (
"fmt"
"io/ioutil"
"net/http"
"strings"
)func main() {
resp, err := http.Post("http://www.baidu.com", "application/x-www.form-urlencoded", strings.NewReader("id=1"))
if err != nil {
panic(err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
fmt.Println(string(body))
}
</pre>
-
GO語言正則表達式
Go語言標準庫內建提供了regexp包
-
正則字母含義
.匹配除換行符以外的任意字符
\w匹配字母或數字或下劃線或漢字
\s匹配任意的空白符
\d匹配數字
\b匹配單詞的開始或結束
^匹配字符串的開始
$匹配字符串的結束
*重復零次或更多次
+重復一次或更多次
?重復零次或一次
{n}重復n次
{n,}重復n次或更多次
{n,m}重復n到m次
捕獲(exp) 匹配exp,并捕獲文本到自動命名的阻組里
(?<name>exp) 匹配exp,并捕獲文本到名稱為name的組里,也可以寫成(?'name'exp)
(?:exp)匹配exp,不捕獲匹配的文本,也不給此分組分配組號
-
正則函數
func Match(pattern string,b []byte)(matched bool,err error)
func MatchString(pattern string,s string)(matched bool,err error)
func MustCompile(str string)*Regexp
func(re * Regexp)FindAllString(s string,n int)[]string
-
代碼演示
-
<pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="" cid="n372" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 1.125rem; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background: inherit; position: relative !important; color: rgb(122, 122, 122); padding: 0.5rem 1.125em; margin-bottom: 0.88em; border: 1px solid rgb(122, 122, 122); margin-top: 0px; line-height: 1.5rem; width: inherit;">package main
import (
"fmt"
"regexp"
)func main() {
isok, _ := regexp.Match("[a-zA-Z]{3}", []byte("zhl"))
fmt.Printf("%v", isok)
reg1 := regexp.MustCompile(^z(.*)l<pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="" cid="n372" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 1.125rem; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background: inherit; position: relative !important; color: rgb(122, 122, 122); padding: 0.5rem 1.125em; margin-bottom: 0.88em; border: 1px solid rgb(122, 122, 122); margin-top: 0px; line-height: 1.5rem; width: inherit;") result1 := reg1.FindAllString("zhangsan", -1) fmt.Printf("%v\n", result1) reg2 := regexp.MustCompile(
z(.{1})(.{1})(.*)l<pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="" cid="n372" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 1.125rem; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background: inherit; position: relative !important; color: rgb(122, 122, 122); padding: 0.5rem 1.125em; margin-bottom: 0.88em; border: 1px solid rgb(122, 122, 122); margin-top: 0px; line-height: 1.5rem; width: inherit;")
result2 := reg2.FindAllStringSubmatch("zhangsan", -1)
fmt.Printf("%v\n", result2)}
</pre>
-
代碼演示2
<pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="" cid="n375" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 1.125rem; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background: inherit; position: relative !important; color: rgb(122, 122, 122); padding: 0.5rem 1.125em; margin-bottom: 0.88em; border: 1px solid rgb(122, 122, 122); line-height: 1.5rem; width: inherit;">package main
import (
"fmt"
"io/ioutil"
"net/http"
"regexp"
)func main() {
url := "https://movie.douban.com/subject/1292052/"
resp, err := http.Get(url)
if err != nil {
panic(err)
}
defer resp.Body.Close()
sHtml, _ := ioutil.ReadAll(resp.Body)
// fmt.Println(string(sHtml))
reg := regexp.MustCompile(<span\s*property="v:itemreviewed">(.*)</span>
)
result := reg.FindAllStringSubmatch(string(sHtml), -1)
// fmt.Printf("%v", result)
// for _, v := range result {
// fmt.Println(v[1])
// }
fmt.Println(result[0][1])
reg1 := regexp.MustCompile(<strong\s*class="ll\s*rating_num"\s*property="v:average">(.*)</strong>
)
result1 := reg1.FindAllStringSubmatch(string(sHtml), -1)
fmt.Println(result1[0][1])
}
</pre>
-
GO語言Mysql與Redis
Go語言使用mysql驅動包:https://github.com/Go-SQL-Driver/Mysql
-
使用sql.open()函數用來打開一個注冊過的數據庫驅動,Go-MySQL-Driver中注冊了mysql這個數據庫的驅動,第二個參數是DNS(Data Source Name),它是Go-MySQL-Driver定義的一些數據庫鏈接和配置信息.它支持如下格式
user@unix(/path/to/socket)/dbname?charset=utf8
user:password@tcp(localhost:5555)/dbname?chaset=utf8
-
Go語言操作mysql代碼
-
<pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="" cid="n390" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 1.125rem; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background: inherit; position: relative !important; color: rgb(122, 122, 122); padding: 0.5rem 1.125em; margin-bottom: 0.88em; border: 1px solid rgb(122, 122, 122); margin-top: 0px; line-height: 1.5rem; width: inherit;">package main
import (
"database/sql"
"fmt"_ "github.com/go-sql-driver/mysql"
)
func main() {
db, err := sql.Open("mysql", "root:123456@tcp(127.0.0.1:3306)/cost?charset=utf8")
if err != nil {
panic(err)
}
//插入
// stmt, err := db.Prepare("insert test set t_id=?,t_name=?,t_time=?")
// res, err := stmt.Exec(998, "zhangsan", "2019-01-02")
// id, err := res.LastInsertId()
//修改
// stmt, err := db.Prepare("update test set t_name=? where t_id=?")
// res, err := stmt.Exec("lisi", 999)
// id, err := res.RowsAffected()
//數據庫一主多從,從庫多是用來查詢的
//查詢
rows, err := db.Query("select * from test where t_id=999")
if err != nil {
panic(err)
}
for rows.Next() {
var t_id int
var t_name string
var t_time string
err = rows.Scan(&t_id, &t_name, &t_time)
fmt.Println(t_id, t_name, t_time)
}
//在go中創建的變量必須調用一次
// fmt.Println(id)
}
</pre>
-
Go語言使用的Redis驅動包:https://github.com/astaxie/goredis
驅動包需設置gopath下載使用
下載安裝redis并啟動
-
redis的基本操作類型
string
hash
set
list
zset
-
redis代碼示例
<pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="" cid="n412" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 1.125rem; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background: inherit; position: relative !important; color: rgb(122, 122, 122); padding: 0.5rem 1.125em; margin-bottom: 0.88em; border: 1px solid rgb(122, 122, 122); line-height: 1.5rem; width: inherit;">package main
import (
"fmt""github.com/astaxie/goredis"
)
func main() {
var client goredis.Client
client.Addr = "127.0.0.1:6379"
//存入數據到redis
err := client.Set("test", []byte("hello beifeng"))
if err != nil {
panic(err)
}
//從redis獲取數據
res, err := client.Get("test")
if err != nil {
panic(err)
}
fmt.Println(string(res))
//庫中hmset方法使用
f := make(map[string]interface{})
f["name"] = "zhangsan"
f["age"] = 12
f["sex"] = "male"
err = client.Hmset("test_hash", f)
if err != nil {
panic(err)
}
//庫中 zset方法使用
_, err = client.Zadd("test_zset", []byte("beifeng"), 100)
if err != nil {
panic(err)
}
}
</pre> -
redis命令行操作查看
- <pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="" cid="n417" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 1.125rem; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background: inherit; position: relative !important; color: rgb(122, 122, 122); padding: 0.5rem 1.125em; margin-bottom: 0.88em; border: 1px solid rgb(122, 122, 122); margin-top: 0px; line-height: 1.5rem; width: inherit;">//啟動服務
redis-server.exe
//啟動客戶端查看數據
E:\quickSorftWare\redis>redis-cli.exe
127.0.0.1:6379> get test
"hello golang"
127.0.0.1:6379> type test_hash
none
127.0.0.1:6379> type test_hash
hash
127.0.0.1:6379> hgetall test_hash- "age"
- "12"
- "sex"
- "male"
- "name"
- "zhangsan"
127.0.0.1:6379> hgetall test_zadd
(empty list or set)
127.0.0.1:6379> type test_zadd
none
127.0.0.1:6379> type test_zset
zset
127.0.0.1:6379> zrange test_zset 0 -1 - "golang"
</pre>
- <pre spellcheck="false" class="md-fences mock-cm md-end-block" lang="" cid="n417" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: Menlo, Monaco, "Courier New", monospace; font-size: 1.125rem; display: block; break-inside: avoid; text-align: left; white-space: pre-wrap; background: inherit; position: relative !important; color: rgb(122, 122, 122); padding: 0.5rem 1.125em; margin-bottom: 0.88em; border: 1px solid rgb(122, 122, 122); margin-top: 0px; line-height: 1.5rem; width: inherit;">//啟動服務