咖啡伴侶

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

          Golang語(yǔ)法與代碼格式速記

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


          // TODO package

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

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

          // 用圓括號(hào)組合導(dǎo)入包,這是“factored”導(dǎo)入語(yǔ)句
          import ("fmt"; "math")
          import (
              "fmt"
              "math"
          )
          // 導(dǎo)入包可以定義別名,防止同名稱的包沖突
          import n "net/http"
          import (
              控制臺(tái) "fmt"
              m "math"
          )
          控制臺(tái).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 的別名,代表一個(gè)Unicode碼點(diǎn)

          // 變量聲明, 使用var關(guān)鍵字    (Go中只能使用var聲明變量,無(wú)需顯式初始化值)
          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 語(yǔ)句聲明了一個(gè)變量的列表,類型在變量名之后
          var a,b,c int    // a = 0, b = 0, c = 0
          var (
              a int    // a = 0
              b string    // b = ""
              c uint    // c = 0
          )

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

          // 初始化使用表達(dá)式時(shí),可以省略類型,變量從初始值中獲得類型
          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ù)外的每個(gè)語(yǔ)法塊都必須以關(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
          )

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

          // 常量組合聲明時(shí), iota每次引用會(huì)逐步自增, 初始值為0,步進(jìn)值為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
          )

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

          // 枚舉序列中的未指定類型的常量會(huì)跟隨序列前面最后一次出現(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自增值只在一個(gè)常量定義組合中有效,跳出常量組合定義后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序列初始值與步進(jìn)值 (通過數(shù)學(xué)公式實(shí)現(xiàn))
          const (
              a = (iota + 2) * 3    // a int32 = 0    (a=(0+2)*3) 初始值為6,步進(jìn)值為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ù)組聲明帶有長(zhǎng)度信息,數(shù)組的長(zhǎng)度固定
          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
          // 使用自動(dòng)計(jì)算數(shù)組初始數(shù)據(jù)的長(zhǎng)度
          var a = []int{0, 1, 2}
          x := [][3]int{{0, 1, 2}, {3, 4, 5}}

          // slice 指向數(shù)組的值,并且同時(shí)包含了長(zhǎng)度信息
          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)建一個(gè)新的 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 來(lái)創(chuàng)建(不是 new);一個(gè)值為 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,    // 最后的逗號(hào)是必須的
          }
          m = map[string]S{
          "a":S{0,1},
          "b":{2,3},    // 類型名稱可省略
          }
          a := m["a"]    // 取值
          a, ok := m["a"]    // 取值, 并通過ok(bool)判斷key對(duì)應(yīng)的元素是否存在.
          delete(m, "a")    // 刪除key對(duì)應(yīng)的元素.

          // 結(jié)構(gòu)體(struct)就是一個(gè)字段的集合, type 定義跟其字面意思相符
          type S struct {
              A int
              B, c string
          }
          type (
              A struct {
                  s *S
              }
              B struct {
                  A    // 組合
              }
          )
          // 結(jié)構(gòu)體文法表示通過結(jié)構(gòu)體字段的值作為列表來(lái)新分配一個(gè)結(jié)構(gòu)體。
          var s S = S{0, "1", "2"}
          // 使用 Name: 語(yǔ)法可以僅列出部分字段。(字段名的順序無(wú)關(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"}

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

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

          // TODO chanel

          // TODO error

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

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

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

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

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

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

          // if語(yǔ)句作用域范圍內(nèi)定義的變量會(huì)覆蓋外部同名變量,(與方法函數(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)。可以讓前置、后置語(yǔ)句為空,或者全為空
          for i := 0; i < 10; i++ {}
          for i := 0; i < 10; {}
          for ; i < 10; i++ {}
          for ; i < 10; {}
          for i < 10 {}
          for ; ; {}
          for {}

          // 小括號(hào) ( )是可選的,而 { } 是必須的。
          for (i := 0; i < 10; i++) {}    // 編譯錯(cuò)誤.
          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ù)或接受多個(gè)參數(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)兩個(gè)或多個(gè)連續(xù)的函數(shù)命名參數(shù)是同一類型,則除了最后一個(gè)類型之外,其他都可以省略
          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() {}
          主站蜘蛛池模板: 道真| 上高县| 本溪市| 视频| 团风县| 万山特区| 芮城县| 北流市| 西峡县| 白水县| 南江县| 万山特区| 全州县| 峡江县| 丰顺县| 冕宁县| 宣汉县| 集贤县| 堆龙德庆县| 布尔津县| 屏山县| 绍兴县| 钦州市| 沧源| 苏尼特右旗| 启东市| 德保县| 密云县| 邵武市| 蓬安县| 玉门市| 高平市| 乐陵市| 宜昌市| 重庆市| 大关县| 荥经县| 增城市| 资溪县| 原平市| 达尔|