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;">//启动服务