咖啡伴侶

          呆在上海
          posts - 163, comments - 156, trackbacks - 0, articles - 2

          Golang語法與代碼格式速記

          Posted on 2013-08-02 16:15 oathleo 閱讀(2432) 評論(0)  編輯  收藏 所屬分類: Golang
          // Description: Golang語法與代碼格式速記
          // Author: cxy
          // Date: 2013-04-01
          // Version: 0.3
          // TODO 說明


          // TODO package

          // Go是采用語法解析器自動在每行末尾增加分號,所以在寫代碼的時候可以把分號省略。
          // Go編程中只有幾個地方需要手工增加分號,如: for循環(huán)使用分號把初始化,條件和遍歷元素分開。在一行中有多條語句時,需要增加分號。
          // 不能把控制語句(if, for, switch, or select)、函數(shù)、方法 的左大括號單獨放在一行, 如果你這樣作了語法解析器會在大括號之前插入一個分號,導(dǎo)致編譯錯誤。

          // 引用包名與導(dǎo)入路徑的最后一個目錄一致
          import "fmt"
          import "math/rand"
          fmt.Println(rand.Intn(10))    // 0到10之間的非負偽隨機數(shù)

          // 用圓括號組合導(dǎo)入包,這是“factored”導(dǎo)入語句
          import ("fmt"; "math")
          import (
              "fmt"
              "math"
          )
          // 導(dǎo)入包可以定義別名,防止同名稱的包沖突
          import n "net/http"
          import (
              控制臺 "fmt"
              m "math"
          )
          控制臺.Println(m.Pi)

          // 首字母大寫的名稱是被導(dǎo)出的, 首字母小寫的名稱只能在同一包內(nèi)訪問(同包跨文件也能訪問)
          var In int // In is public
          var in byte // in is private
          var 看不見 string // 看不見 is private
          const Com bool = false // Com is public
          const 還是看不見 uint8 = 1 // 還是看不見 is private
          type Integer int // Integer is public
          type ブーリアン *bool // ブーリアン is private
          func Export() {// Export is public
          func 導(dǎo)入() {// 導(dǎo)入 is private
          func (me *Integer) valueOf(s stringint {// valueOf is private
          func (i ブーリアン) String() string {// String is public

          // Go 的基本類型:
          ┌──────┬─────────┬────────┬─────────┬───────────┬────────────┐
          │ bool │ string  │        │         │           │            │
          ├──────┼─────────┼────────┼─────────┼───────────┼────────────┤
          │ int  │ int8    │ int16  │ int32   │ int64     │            │
          │      │         │        │ rune    │           │            │
          ├──────┼─────────┼────────┼─────────┼───────────┼────────────┤
          │ uint │ uint8   │ uint16 │ uint32  │ uint64    │ uintptr    │
          │      │ byte    │        │         │           │            │
          ├──────┼─────────┼────────┼─────────┼───────────┼────────────┤
          │      │         │        │ float32 │ float64   │            │
          ├──────┼─────────┼────────┼─────────┼───────────┼────────────┤
          │      │         │        │         │ complex64 │ complex128 │
          └──────┴─────────┴────────┴─────────┴───────────┴────────────┘
          // byte 是 uint8 的別名
          // rune 是 int32 的別名,代表一個Unicode碼點

          // 變量聲明, 使用var關(guān)鍵字    (Go中只能使用var聲明變量,無需顯式初始化值)
          var i int    // i = 0
          var s string    // s = ""    (Go中的string不存在nil(null)值,默認(rèn)零值就是空串 "" 或 ``)
          var e error    // e = nil, error是Go的內(nèi)建接口類型,不是基本類型。

          // var 語句聲明了一個變量的列表,類型在變量名之后
          var a,b,c int    // a = 0, b = 0, c = 0
          var (
              a int    // a = 0
              b string    // b = ""
              c uint    // c = 0
          )

          // 變量定義時初始化賦值,每個變量對應(yīng)一個值
          var a int = 0
          var a,b int = 0, 1

          // 初始化使用表達式時,可以省略類型,變量從初始值中獲得類型
          var a = 'A'    // a int32
          c := 1 + 2i    // c complex128
          var a,b = 0, "B"    // a int, b string
          a, b := 0, "B"    // a int, b string
          c := `formatted
           string`    // c string

          // := 結(jié)構(gòu)不能使用在函數(shù)外,函數(shù)外的每個語法塊都必須以關(guān)鍵字開始

          // 常量可以是字符、字符串、布爾或數(shù)字類型的值,數(shù)值常量是高精度的值
          const x int = 3
          const (
              a byte = 'A'
              b string = "B"
              c bool = true
              d int = 4
              e float32 = 5.1
              f complex64 = 6 + 6i
          )

          // 未指定類型的常量由常量值決定其類型
          const a = 0    // a int
          const (
              b = 2.3    // b float64
              c = true    // c bool
          )

          // 自動枚舉常量 iota
          // iota的枚舉值可以賦值給數(shù)值兼容類型
          // 每個常量單獨聲明時, iota不會自動遞增(無意義)
          const a int = iota    // a = 0
          const b int = iota    // b = 0
          const c byte = iota    // c = 0
          const d uint64 = iota    // d = 0

          // 常量組合聲明時, iota每次引用會逐步自增, 初始值為0,步進值為1
          const (
              a uint8 = iota    // a = 0
              b int16 = iota    // b = 1
              c rune = iota    // c = 2
              d float64 = iota    // d = 3
              e uintptr = iota    // e = 4
          )

          // 枚舉的常量都為同一類型時, 可以使用簡單序列格式.
          const (
              a = iota    // a int32 = 0
              b            // b int32 = 1
              c            // c int32 = 2
          )

          // 枚舉序列中的未指定類型的常量會跟隨序列前面最后一次出現(xiàn)類型定義的類型
          const (
              a byte = iota    // a uint8 = 0
              b                // b uint8 = 1
              c                // c uint8 = 2
              d rune = iota    // d int32 = 3
              e                // e int32 = 4
              f                // f int32 = 5
          )

          // iota自增值只在一個常量定義組合中有效,跳出常量組合定義后iota值歸0
          const (
              a = iota    // a int32 = 0
              b            // b int32 = 1
              c            // c int32 = 2
          )
          const (
              e = iota    // e int32 = 0    (iota重新初始化并自增)
              f            // f int32 = 1
          )

          // 定制iota序列初始值與步進值 (通過數(shù)學(xué)公式實現(xiàn))
          const (
              a = (iota + 2) * 3    // a int32 = 0    (a=(0+2)*3) 初始值為6,步進值為3
              b                    // b int32 = 3    (b=(1+2)*3)
              c                    // c int32 = 6    (c=(2+2)*3)
              d                    // d int32 = 9    (d=(3+2)*3)
          )

          // 數(shù)組聲明帶有長度信息,數(shù)組的長度固定
          var a [3]int = [3]int{0, 1, 2}    // a = [0 1 2]
          var b [3]int = [3]int{}    // b = [0 0 0]
          var c = [3]int{}    // c = [0 0 0]
          d := [3]int{}    // d = [0 0 0]
          fmt.Printf("%T\t%#v\t%d\t%d\n", d, d, len(d), cap(d))    // [3]int    [3]int{0, 0, 0}    3    3
          // 使用自動計算數(shù)組初始數(shù)據(jù)的長度
          var a = []int{0, 1, 2}
          x := [][3]int{{0, 1, 2}, {3, 4, 5}}

          // slice 指向數(shù)組的值,并且同時包含了長度信息
          var a []int
          fmt.Printf("%T\t%#v\t%d\t%d\n", a, a, len(a), cap(a))    // []int    []int(nil)    0    0
          var a = new([]int)
          fmt.Printf("%T\t%#v\t%d\t%d\n", a, a, len(*a), cap(*a))    // *[]int    &[]int(nil)    0    0
          var b = make([]int, 0)
          fmt.Printf("%T\t%#v\t%d\t%d\n", b, b, len(b), cap(b))    // []int    []int{}    0    0
          var c = make([]int, 3, 10)
          fmt.Printf("%T\t%#v\t%d\t%d\n", c, c, len(c), cap(c))    // []int    []int{}    3    10
          var d []int = []int{0, 1, 2}
          fmt.Printf("%T\t%#v\t%d\t%d\n", d, d, len(d), cap(d))    // []int    []int{0, 1, 2}    3    3

          // slice 可以重新切片,創(chuàng)建一個新的 slice 值指向相同的數(shù)組
          s := []int{0, 1, 2, 3, 4}
          fmt.Println(s[1,3])    // [1 2]    (截取從開始索引到結(jié)束索引-1 之間的片段)
          fmt.Println(s[:4])    // [0 1 2 3]
          fmt.Println(s[1:])    // [1 2 3 4]
          fmt.Println(s[1:1])    // []

          // 向slice中添加元素
          s := make([]string, 3)
          s = append(s, "a")


          // map 在使用之前必須用 make 來創(chuàng)建(不是 new);一個值為 nil 的 map 是空的,并且不能賦值
          var m map[int]int
          m[0] = 0    // × runtime error: assignment to entry in nil map
          fmt.Printf("type: %T\n", m)    // map[int]int
          fmt.Printf("value: %#v\n", m)    // map[int]int(nil)
          fmt.Printf("value: %v\n", m)    // map[]
          fmt.Println("is nil: ", nil == m)    // true
          fmt.Println("length: ", len(m))    // 0,if m is nil, len(m) is zero.

          var m map[int]int = make(map[int]int)
          m[0] = 0    // 插入或修改元素
          fmt.Printf("type: %T\n", m)        // map[int]int
          fmt.Printf("value: %#v\n", m)        // map[int]int(0:0)
          fmt.Printf("value: %v\n", m)        // map[0:0]
          fmt.Println("is nil: ", nil == m)    // false
          fmt.Println("length: ", len(m))        // 1

          m = map[int]int{
          0:0,
          1:1,    // 最后的逗號是必須的
          }
          m = map[string]S{
          "a":S{0,1},
          "b":{2,3},    // 類型名稱可省略
          }
          a := m["a"]    // 取值
          a, ok := m["a"]    // 取值, 并通過ok(bool)判斷key對應(yīng)的元素是否存在.
          delete(m, "a")    // 刪除key對應(yīng)的元素.

          // 結(jié)構(gòu)體(struct)就是一個字段的集合, type 定義跟其字面意思相符
          type S struct {
              A int
              B, c string
          }
          type (
              A struct {
                  s *S
              }
              B struct {
                  A    // 組合
              }
          )
          // 結(jié)構(gòu)體文法表示通過結(jié)構(gòu)體字段的值作為列表來新分配一個結(jié)構(gòu)體。
          var s S = S{0, "1", "2"}
          // 使用 Name: 語法可以僅列出部分字段。(字段名的順序無關(guān)。)
          var s S = S{A: 0, B: "1"}
          var s S = S{}
          // 特殊的前綴 & 構(gòu)造了指向結(jié)構(gòu)體文法的指針。
          var s *S = &S{0, "1", "2"}

          // 表達式 new(T) 分配了一個零初始化的 T 值,并返回指向它的指針
          var s *S = new(S)
          // 有指針,但是沒有指針運算,結(jié)構(gòu)體字段使用點號來訪問
          // 結(jié)構(gòu)體字段可以通過結(jié)構(gòu)體指針來訪問。通過指針間接的訪問是透明的
          fmt.Println(s.A)
          fmt.Println((*s).A)

          // TODO interface
          type IF interface {
              a()
          }

          // TODO chanel

          // TODO error

          // if 語句 小括號 ( )是可選的,而 { } 是必須的。
          if (i < 0)        // 編譯錯誤.
              println(i)

          if i < 0        // 編譯錯誤.
              println(i)

          if (i < 0) {    // 編譯通過.
              println(i)
          }
          if i < 0 {
              println(i)
          else {
              println(i)
          }

          // 可以在條件之前執(zhí)行一個簡單的語句,由這個語句定義的變量的作用域僅在 if/else 范圍之內(nèi)
          if (i := 0; i < 1) {    // 編譯錯誤.
              println(i)
          }

          if i := 0; (i < 1) {    // 編譯通過.
              println(i)
          }

          if i := 0; i < 0 {    // 使用gofmt格式化代碼會自動移除代碼中不必要的小括號( )
              println(i)
          else if i == 0 {
              println(i)
          else {
              println(i)
          }

          // if語句作用域范圍內(nèi)定義的變量會覆蓋外部同名變量,(與方法函數(shù)內(nèi)局部變量覆蓋全局變量相同)
          a, b := 0, 1
          if a, b := 3, 4; a > 1 && b > 2 {
              println(a, b)    // 3 4
          }
          println(a, b)    // 0 1


          // 只有一種循環(huán)結(jié)構(gòu),for 循環(huán)。可以讓前置、后置語句為空,或者全為空
          for i := 0; i < 10; i++ {}
          for i := 0; i < 10; {}
          for ; i < 10; i++ {}
          for ; i < 10; {}
          for i < 10 {}
          for ; ; {}
          for {}

          // 小括號 ( )是可選的,而 { } 是必須的。
          for (i := 0; i < 10; i++) {}    // 編譯錯誤.
          for i := 0; (i < 10); i++ {}    // 編譯通過.
          for (i < 10) {}    // 編譯通過.

          // TODO continue

          // TODO for range

          // TODO switch
          // TODO fallthrough break
          // TODO type assertion

          // TODO select

          // TODO goto

          // 函數(shù)可以沒有參數(shù)或接受多個參數(shù)
          func f() {}
          func f(a int) {}
          func f(a int, b byte) {}
          func f(a int) {}    // 可變參數(shù)
          func f(a int, b bool, c string) {}
          // 函數(shù)可以返回任意數(shù)量的返回值
          func f() int {
              return 0
          }
          func f() intstring {
              return 0, "A"
          }
          // 函數(shù)返回結(jié)果參數(shù),可以像變量那樣命名和使用
          func f() a int, b string {
              a = 1
              b = "B"
              return    // 或者 return a, b
          }

          // 當(dāng)兩個或多個連續(xù)的函數(shù)命名參數(shù)是同一類型,則除了最后一個類型之外,其他都可以省略
          func f(a,b,c int) {}
          func f() a,b,c int {}
          func f(a,b,c int) x,y,z int {}

          // 函數(shù)也是值,可以將函數(shù)賦值給變量
          var f (func(i intint) = func(i intint {
              return i
          }
          fmt.Println(f(3))    // 3
          var f func() int = func() int {
              return 0
          }
          fmt.Println(f())    // 0
          var f func() = func() {}
          var f = func() {}
          f := func() {}

          // TODO defer

          // TODO 方法

          // TODO 內(nèi)建函數(shù)
          append 
          cap 
          close 
          complex 
          copy 
          delete 
          imag 
          len 
          make 
          new 
          panic 
          print 
          println 
          real 
          recover

          // TODO 并發(fā)
          go func() {}
          主站蜘蛛池模板: 淅川县| 通化县| 于田县| 黑山县| 诸暨市| 康平县| 郁南县| 依兰县| 秦安县| 和平县| 万源市| 白山市| 沭阳县| 桑植县| 遂平县| 新余市| 鹤山市| 石城县| 五大连池市| 沈阳市| 城市| 宁晋县| 托克逊县| 玛多县| 宜良县| 中江县| 丽水市| 永登县| 隆昌县| 高阳县| 巴塘县| 开封市| 舒兰市| 克拉玛依市| 和硕县| 柳林县| 驻马店市| 达孜县| 台南县| 呼伦贝尔市| 尚志市|