Go語言入坑

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>
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>
    • 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>
    • 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>
  • 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>
  • 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>

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>
  • 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="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>
    • 在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>

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>
  • 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>
    • 緩存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>
      • 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 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))
      }
      </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, &quot;Courier New&quot;, 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
      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
      7. "golang"
        </pre>

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,818評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,185評論 3 414
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,656評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,647評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,446評論 6 405
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,951評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,041評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,189評論 0 287
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,718評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,602評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,800評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,316評論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,045評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,419評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,671評論 1 281
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,420評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,755評論 2 371

推薦閱讀更多精彩內容

  • 一、數據類型轉換 https://studygolang.com/articles/10838 package m...
    蓓蓓的萬能男友閱讀 1,098評論 0 1
  • fmt格式化字符串 格式:%[旗標][寬度][.精度][arg索引]動詞旗標有以下幾種:+: 對于數值類型總是輸出...
    皮皮v閱讀 1,116評論 0 3
  • Golang是我最喜歡的一門語言,它簡潔、高效、易學習、開發效率高、還可以編譯成機器碼… 雖然它一出世,就飽受關注...
    盤木閱讀 3,568評論 0 7
  • /* gotips_test.go: Golang速學速查速用代碼手冊 Source: github.com/c...
    中v中閱讀 275評論 0 0
  • 安裝 官網下載地址:https://golang.org/dl/ ,根據系統平臺下載對應資源包,安裝或解壓到對應目...
    魚籽灬閱讀 719評論 0 0