<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      Golang筆記

      Posted on 2022-11-27 22:13  呱呱呱呱嘰里呱啦  閱讀(57)  評論(0)    收藏  舉報

      Golang筆記

      Hello World!

      package main
      
      import "fmt"
      
      func main() {
          fmt.Println("Hello World!")
      }
      

      變量定義

      package main
      
      import "fmt"
      
      func varInit() {
          var a, b int = 3, 4
          var s = "Hello"
          c, d := true, 3.14
          var (
              e = "你"
              f = 6
          )
          fmt.Println(a, b, s, c, d, e, f)
      }
      
      func main() {
          varInit()
      }
      

      內建類型

      • bool

      • string

      • 有無符號的int, int8, int16, int32, int64

      • uintptr

      • byte = uint8

      • rune= uint32

      • float32, float64, complex64, complex128

      • 強制類型轉換

      常量與枚舉

      package main
      
      import "fmt"
      
      func consts() {
          const filename = "a.txt"
          const (
              a = 1
              b = 2
          )
          fmt.Println(filename, a, b)
      }
      
      func enums() {
          const (
              windows = iota
              linux
              mac
          )
          const (
              b = 1 << (10 * iota)
              kb
              mb
              gb
              tb
              pb
          )
          fmt.Println(windows, linux, mac)
          fmt.Println(b, kb, mb, gb, tb, pb)
      
      }
      
      func main() {
          consts()
          enums()
      }
      

      條件語句

      package main
      
      import (
          "fmt"
          "io/ioutil"
      )
      
      func main() {
          const filename = "a.txt"
          if content, err := ioutil.ReadFile(filename); err != nil {
              fmt.Println(err)
          } else {
              fmt.Println(content)
          }
      }
      

      循環語句

      package main
      
      import (
          "fmt"
          "strconv"
      )
      
      func convertToBin(n int) string {
          result := ""
          for ; n > 0; n /= 2 {
              result = strconv.Itoa(n%2) + result
          }
          return result
      }
      func main() {
          fmt.Println(convertToBin(5))
      }
      

      函數

      package main
      
      import (
          "fmt"
      )
      
      func eval(a, b int, op string) (int, error) {
          switch op {
          case "+":
              return a + b, nil
          case "-":
              return a - b, nil
          case "*":
              return a * b, nil
          case "/":
              return a / b, nil
          default:
              return 0, fmt.Errorf("unsupported operation: %s", op)
      
          }
      }
      func main() {
          fmt.Println(eval(1, 2, "*"))
      }
      

      指針

      package main
      
      import (
          "fmt"
      )
      
      func swap(a, b *int) {
          *a, *b = *b, *a
      }
      
      func main() {
          a, b := 2, 3
          // go里的參數傳遞都是值傳遞,對于比較大的數據使用指針可以避免資源浪費
          swap(&a, &b)
          fmt.Println(a, b)
      }
      ntln(a, b)
      }
      

      數組

      package main
      
      import "fmt"
      
      func main() {
          // 數組是值類型
          var (
              arr1 [6]int
              arr2 = [3]int{1, 2, 3}
              arr3 = [...]int{4, 5, 6}
          )
          fmt.Println(arr1, arr2, arr3)
          // range關鍵字
          for i := range arr2 {
              fmt.Println(i)
          }
          for i, v := range arr2 {
              fmt.Println(i, v)
          }
      }
      

      切片

      package main
      
      import "fmt"
      
      func modifyArr(s []int) {
          s[0] = 99
      }
      
      func printSlice(s []int) {
          fmt.Printf("len=%d, cap=%d", len(s), cap(s))
          fmt.Println("")
      }
      
      func main() {
          var sli []int // nil
          printSlice(sli)
          sli = append(sli, 0)
          printSlice(sli)
          sli1 := make([]int, 8)
          fmt.Println(sli1)
      
          arr := [...]int{0, 1, 2, 3, 4}
          // s是對arr的一個view,使用切片可以不傳指針而方便地修改數組
          s := arr[1:3]
          fmt.Println(s)
          modifyArr(s)
          fmt.Println(s)   // [99 2]
          fmt.Println(arr) // [0 99 2 3 4]
          s1 := s[1:3]
          fmt.Println(s1) // [2 3]
          // slice: ptr(指向切片起始位置), len,cap(從起始位置到數組末尾的長度)
          // s[i]不可超越len,s[:n]不可超越cap
          s2 := append(s1, 100)
          fmt.Println(s2)  // [2, 3, 100]
          fmt.Println(arr) // [0 99 2 3 100]
      
          originSSlice := []int{0, 1, 2, 3, 4}
          destSlice := make([]int, 16)
          copy(destSlice, originSSlice)
          fmt.Println(destSlice) // [0 1 2 3 4 0 0 0 0 0 0 0 0 0 0 0]
      
          deleteRes := append(originSSlice[:2], originSSlice[3:]...)
          fmt.Println(deleteRes)    // [0 1 3 4]
          fmt.Println(originSSlice) // [0 1 3 4 4]
      }
      

      Map

      package main
      
      import "fmt"
      
      func main() {
          m := map[string]int{
              "Windows": 0,
              "Mac":     1,
              "Linux":   100,
          }
          m1 := make(map[string]string)
          var m2 map[string]int
          fmt.Println(m1, m2 == nil) // map[] true
          // python3.5之后dict是有序的,但map是無序的
          for k, v := range m {
              fmt.Println(k, v)
          }
          fmt.Println(m["android"]) // 會取到對應類型的零值
          val, ok := m["nothing"]
          fmt.Println(val, ok) // 0 false
          delete(m, "Windows")
          fmt.Println(m)
      }
      
      尋找最長不含重估字符的字串
      package main
      
      func solute(s string) {
          m := make(map[rune]int)
          start := 0
          maxLen := 0
          for i, v := range []rune(s) {
              if old, ok := m[v]; ok && old >= start {
                  start = old + 1
              }
              if i-start+1 > maxLen {
                  maxLen = i - start + 1
              }
              m[v] = i
          }
          print(maxLen)
      }
      
      func main() {
          solute("pwwkew")
      }
      

      結構體

      package main
      
      import "fmt"
      
      type TreeNode struct {
          value       int
          left, right *TreeNode
      }
      
      func CreateNode(value int) *TreeNode {
          // 返回局部變量的地址并不會使外界調用時的代碼出現問題
          return &TreeNode{value: value}
      }
      
      func (node TreeNode) PrintNode() {
          fmt.Println(node.value)
      }
      
      // 需要改變內容、結構過大時應使用指針接收者;保持接收者類型一致性
      // 接受者類型并不會直接影響調用
      
      func (node *TreeNode) SetNode(value int) {
          // 使用指針接收者以方便修改數據
          if node == nil {
              // nil指針也可以調用方法
              fmt.Println("Ignored")
              return
          }
          node.value = value
      }
      
      func (node *TreeNode) Traverse() {
          if node == nil {
              // 邊界條件
              return
          }
          node.left.Traverse()
          node.PrintNode()
          node.right.Traverse()
      }
      
      func main() {
          root := TreeNode{value: 3}
          root.left = &TreeNode{4, nil, nil}
          root.right = &TreeNode{5, nil, nil}
          root.right.left = new(TreeNode)
          root.left.right = CreateNode(6)
          root.Traverse()
      }
      

      封裝

      • 每個目錄為一個包(不要求包名和目錄名一致)

      • main包包含可執行入口

      • 為結構定義的方法必須放在同一個包內(的相同或者不同文件)

      針對包的權限:標識符首字母大寫代表public、首字母小寫代表private

      擴充已有(系統或自定義)類型

      • 使用組合
      package trn
      
      import "fmt"
      
      type TreeNode struct {
          Value       int
          Left, Right *TreeNode
      }
      
      func CreateNode(value int) *TreeNode {
          return &TreeNode{Value: value}
      }
      
      func (node *TreeNode) PrintNode() {
          fmt.Println(node.Value)
      }
      
      func (node *TreeNode) SetNode(value int) {
          if node == nil {
              fmt.Println("Ignored")
              return
          }
          node.Value = value
      }
      
      func (node *TreeNode) Traverse() {
          if node == nil {
              return
          }
          node.Left.Traverse()
          node.PrintNode()
          node.Right.Traverse()
      }
      
      
      
      package main
      
      import "go_code/trn"
      
      type myTreeNode struct {
          node *trn.TreeNode
      }
      
      func (myNode *myTreeNode) TraverseL() {
          if myNode == nil || myNode.node == nil {
              return
          }
          (&myTreeNode{myNode.node.Left}).TraverseL()
          (&myTreeNode{myNode.node.Right}).TraverseL()
          myNode.node.PrintNode()
      }
      
      func main() {
          root := trn.TreeNode{Value: 3}
          root.Left = &trn.TreeNode{4, nil, nil}
          root.Right = &trn.TreeNode{5, nil, nil}
          root.Right.Left = new(trn.TreeNode)
          root.Left.Right = &trn.TreeNode{Value: 6}
          test := myTreeNode{&root}
          test.TraverseL()
      }
      
      • 定義別名
      package queue
      
      type Q []int
      
      func (q *Q) Push(value int) {
          *q = append(*q, value)
      }
      
      func (q *Q) Pop() int {
          tail := (*q)[len(*q)-1]
          *q = (*q)[:len(*q)-1]
          return tail
      }
      
      func (q *Q) IsEmpty() bool {
          return len(*q) == 0
      }
      
      package main
      
      import (
          "fmt"
          "go_code/queue"
      )
      
      func main() {
          q := queue.Q{1}
          q.Push(2)
          q.Push(3)
          fmt.Println(q)
          fmt.Println(q.IsEmpty())
          fmt.Println(q.Pop())
          fmt.Println(q)
          fmt.Println(q.IsEmpty())
          fmt.Println(q.Pop())
          fmt.Println(q)
          fmt.Println(q.IsEmpty())
      }
      
      • 內嵌
      package main
      
      import "go_code/trn"
      
      type myTreeNode struct {
          *trn.TreeNode // 內嵌
      }
      
      func (myNode *myTreeNode) Traverse() {
          if myNode == nil || myNode.TreeNode == nil {
              return
          }
          // 減少代碼量myNode.TreeNode.Left -> myNode.Left
          (&myTreeNode{myNode.Left}).Traverse()
          (&myTreeNode{myNode.Right}).Traverse()
          myNode.PrintNode()
      }
      
      func main() {
          // myTreeNode自動獲取內嵌結構體的屬性和方法
          root := myTreeNode{&trn.TreeNode{Value: 3}}
          root.Left = &trn.TreeNode{4, nil, nil}
          root.Right = &trn.TreeNode{5, nil, nil}
          root.Right.Left = new(trn.TreeNode)
          root.Left.Right = &trn.TreeNode{Value: 6}
          // 相較于傳統面向對象的重載,內嵌仍可調用被shadowed的方法,
          // 但不是通過子類對象賦值基類
          root.Traverse()
          root.TreeNode.Traverse()
      }
      

      依賴管理

      1. GOPATH:擺爛管理

      2. GO VENDER:打補丁

      3. GO MOD:直接用

      GOPATH
      go env -w GOPATH=
      go env -w GO111MODULE=off
      
      # 臨時
      export GOPATH=
      export GO111MODULE=off
      
      mkdir src
      
      go get -u xxx.xxx.org/xxx
      
      GO VENDER

      每個項目下自建vender目錄管理自己的庫

      GO MOD

      import 路徑 = go mod 下的module name + 包相對于go mod的相對目錄

      go env -w GO111MODULE=on
      # 切換本地代理
      go env -w GOPROXY=https://goproxy.cn,direct
      go get -u xxx.xxx.org/xxx@vn.nn
      # 清理無用版本
      go mod tidy
      
      舊項目遷移GO MOD
      go env -w GO111MODULE=on
      # 切換本地代理
      go env -w GOPROXY=https://goproxy.cn,direct
      go mod init modname
      # 檢查編譯是否可以通過,編譯全部子目錄文件可以考慮使用go install ./...
      go build ./...
      

      go中沒有類似python中的__name__ == '__main__'的用法,所以如果要寫不同的main入口只能將其放入不同目錄

      接口

      • Go中接口的實現是隱式的
      // retriever/main.go
      package main
      
      import (
      	"fmt"
      	"learn1/retriever/test"
      	"learn1/retriever/web"
      	"time"
      )
      
      type Retriever interface {
      	Get(url string) string
      }
      
      func download(r Retriever) string {
      	return r.Get("http://www.baidu.com")
      }
      
      func main() {
      	var r Retriever
      	r = web.Retriever{TimeOut: time.Minute}
      	fmt.Println(download(r))
      	r = test.Retriever{Contents: "測試"}
      	fmt.Println(download(r))
      }
      
      
      // retriever/test/retriever.go
      package test
      
      type Retriever struct {
      	Contents string
      }
      
      func (r Retriever) Get(url string) string {
      	return r.Contents
      }
      
      
      // retriever/web/retriever.go
      package web
      
      import (
      	"net/http"
      	"net/http/httputil"
      	"time"
      )
      
      type Retriever struct {
      	TimeOut time.Duration
      }
      
      func (r Retriever) Get(url string) string {
      	response, err := http.Get(url)
      	if err != nil {
      		panic(err)
      	}
      	bytes, err := httputil.DumpResponse(response, true)
      	response.Body.Close()
      	if err != nil {
      		panic(err)
      	}
      	return string(bytes)
      }
      
      • 接口變量包含了實現者類型信息和實現者值信息
      // retriever/main.go
      package main
      
      import (
      	"fmt"
      	"learn1/retriever/test"
      	"learn1/retriever/web"
      	"time"
      )
      
      type Retriever interface {
      	Get(url string) string
      }
      
      func download(r Retriever) string {
      	return r.Get("http://www.baidu.com")
      }
      
      func main() {
      	var r Retriever
      	r = web.Retriever{TimeOut: time.Minute}
      	//fmt.Println(download(r))
      	r = test.Retriever{Contents: "測試"}
      	//fmt.Println(download(r))
      	// type assertion
      	if testRetriever, ok := r.(test.Retriever); ok {
      		fmt.Println(testRetriever.Contents)
      	} else {
      		fmt.Println("web.Retriever")
      	}
      }
      
      • 接口變量自帶指針
      • 接口變量同樣采用值傳遞,幾乎不需要使用接口的指針
      • 指針接收者實現只能以指針方式使用,值接收者則無此限制
      • 任何類型:interface{}
      • 接口的組合
      type Retriever interface {
      	Get(url string) string
      }
      
      type Poster interface {
      	Post(url string) string
      }
      
      type WebTool interface {
      	Retriever
      	Poster
      	Delete(target map[string]string) bool
      }
      
      • 常用系統接口(很像Python中的某些魔法方法)
        1. Stringer
        2. Reader
        3. Writer

      函數式編程

      閉包

      錯誤處理與資源管理

      defer

      1. 類似棧,在函數返回前執行,多個defer語句先定義的后執行
      2. defer語句中的變量定義時確定值

      panic

      1. 停止當前函數執行
      2. 一直向上范圍,執行每一層的defer
      3. 如果沒有遇見recover,程序退出

      recover

      1. 僅在defer調用中使用
      2. 獲取panic的值
      3. 可重新panic

      測試

      表格驅動測試

      // learn_t/triangle.go
      package main
      
      import "math"
      
      func triangle(a, b int) int {
      	return int(math.Sqrt(float64(a*a + b*b)))
      }
      
      
      //learn_t/triangle_test.go
      package main
      
      import "testing"
      
      func TestTriangle(t *testing.T) {
      	tests := []struct{ a, b, c int }{
      		{3, 4, 5},
      		{5, 12, 13},
      		{6, 8, 10},
      		{30000, 40000, 50001},
      	}
      	for _, te := range tests {
      		if actual := triangle(te.a, te.b); actual != te.c {
      			t.Errorf("triangle(%d, %d) got %d expected %d", te.a, te.b, actual, te.c)
      		}
      	}
      
      }
      // terminal
      // go test .
      

      代碼覆蓋率

      #代碼覆蓋率
      go test -coverprofile=c.out
      #輸出html
      go tool cover -html=c.out
      
      // 性能測試
      // learn_t/triangle_test.go
      package learn1
      
      import "testing"
      
      func BenchmarkTriangle(b *testing.B) {
      	x, y, z := 3, 4, 5
      	for i := 0; i < b.N; i++ {
      		if actual := triangle(x, y); actual != z {
      			b.Errorf("triangle(%d, %d) got %d expected %d", x, y, actual, z)
      		}
      	}
      
      }
      // terminal
      // go test -bench .
      
      主站蜘蛛池模板: 成全世界免费高清观看| 国产福利深夜在线播放| 最近中文字幕日韩有码| 91久久夜色精品国产网站| 国产性色的免费视频网站| 国产自产av一区二区三区性色| 少妇xxxxx性开放| 自拍日韩亚洲一区在线| 中文字幕国产精品自拍| 蜜臀av一区二区三区在线| 亚洲欧洲美洲无码精品va| 欧美高清freexxxx性| 丝袜美腿亚洲综合在线观看视频| 性做久久久久久久久| 国产成人a在线观看视频| 丰满的熟妇岳中文字幕| 久久九九精品99国产精品| 国产互换人妻xxxx69| 国产午夜A理论毛片| 色老头亚洲成人免费影院| 久久精品免视看国产成人| 日韩av毛片福利国产福利| 亚洲一国产一区二区三区| 又黄又刺激又黄又舒服| 黄又色又污又爽又高潮| 欧美野外伦姧在线观看| 日韩成人无码影院| 国产av黄色一区二区三区| 女人腿张开让男人桶爽 | 男女男免费视频网站国产| 亚洲av男人电影天堂热app| 欧美日韩一线| 热久久这里只有精品国产| 苏尼特右旗| 亚洲欧洲国产综合一区二区 | 英超| 永久免费无码av在线网站| 久久av高潮av喷水av无码| 国产精品中文字幕第一页| 国产乱码精品一区二区三| 国产一级小视频|