package main
import "fmt"
func main(){
//go语言不强制加分号
fmt.Print("Hello word")
}
//cmd输入 go run hello.go输出结果
创建应用编译
y:=“hello” //简短声明的使用,可定义多个
代码:
package main
import "fmt"
func main() {
var x int
x = 1
//这种用法须在函数体内
y, z := "go demo", 2
fmt.Printf("%d %s %d", x, y, z)
}
数组的定义
其它数据类型的使用
s:=make([]int,10,20)//slice动态数组对象
map:student:=make(map[string]int)
流程控制语句
if语句
for
func main() {
sum := 0
x := 1
for x <= 100 {
sum += x
x++
}
fmt.Print(sum)
}
switch
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")
}
for循环
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)
}
Go语言函数
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))
go语言中指针的概念
defer关键词使执行顺序倒着走,退出或资源关闭时使用
defer func() {
fmt.Println("After defer")
}()
fmt.Println("befor defer")
//defer语句遇到异常继续执行
Go语言结构struct
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)
}
简单定义使用
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))
}
go中类的初始化
point:=new(Point)
point:=&Point{}
point:=&Point{x:100,y:100}
point:=Point{}
定义与使用示例
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)
}
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)
}
Go语言接口
在go语言中,一个类只需要实现了接口要求的所有函数,我们就说这个类实现了该接口
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()
}
在Go语言中空间口类似泛型
var v1=interface{}
v1=6.78
fmt.Print(v1)
//类型查询,看接口接收的什么类型
if v, ok := v1.(float64); ok {
fmt.Println(v, ok)
}
与传统的系统级线程相比,协程的大优势在于其"轻量级",可以轻松创建上百万个而不会导致系统资源衰竭,而线程和进程通常多也不能超过1万个,这也是协程也叫轻量级线程的原因.
go对协程的实现:go+函数名:启动一个协程执行函数体
package main
import (
"fmt"
"time"
)
func test_Routine() {
fmt.Println("This is one routine!")
}
func main() {
go test_Routine()
time.Sleep(1)
}
Go并发编程之channel
Channel:Go语言在语言级别提供的goroutine间的通讯方式
声明方式:var chanName chan ElementType
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
}
}
缓存channel
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)
}
select
是linux很早就引入的函数,用来实现非阻塞的一种方式
go语言提供语言级别支持slelect关键字,用于处理异步IO问题
select{
case <-chan1://如果chan1成功读取到数据,则进行该case处理语句
case chan2 <-1://如果成功向chan2写入数据,则进行该case处理
default: //如果上面都没有成功,则进入default处理流程
}
select 三个代码示例
示例1
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!")
}
}
示例2
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!")
}
示例3
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!")
}
深入Go协程编程
协程与线程质的不同
线程与协程代码对比(线程几百个就卡,协程十万个都不算多)
Java线程
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);
}
}
}
Go协程
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)
}
使用的库
json使用代码
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)
}
md5使用
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)
}
go语言标准库内建提供了net/http包
处理http请求:使用net/http包提供的http.ListenAndServer()方法,可以在指定的地址进行监听,开启一个HTTP.服务端该方法的原型如下:func ListenAndServe(addr string,hander Handler)error
处理https请求
http中get和postdaima
//get代码
package main
import (
"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 main
import (
"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))
}
正则字母含义
正则函数
代码演示
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$`)
result1 := reg1.FindAllString("zhangsan", -1)
fmt.Printf("%v\n", result1)
reg2 := regexp.MustCompile(`z(.{1})(.{1})(.*)l$`)
result2 := reg2.FindAllStringSubmatch("zhangsan", -1)
fmt.Printf("%v\n", result2)
}
代码演示2
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])
}
使用sql.open()函数用来打开一个注册过的数据库驱动,Go-MySQL-Driver中注册了mysql这个数据库的驱动,第二个参数是DNS(Data Source Name),它是Go-MySQL-Driver定义的一些数据库链接和配置信息.它支持如下格式
Go语言操作mysql代码
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)
}
驱动包需设置gopath下载使用
redis的基本操作类型
redis代码示例
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)
}
}
redis命令行操作查看
//启动服务
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
1) "age"
2) "12"
3) "sex"
4) "male"
5) "name"
6) "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
1) "golang"