亚洲成A人片在线观看网站_成年网站免费视频A在线双飞_日日日日做夜夜夜夜无码_久久夜色撩人精品国产小说

Golang 備忘清單

該備忘單提供了幫助您(nin)使用 的基(ji)本語法和方法。

入門

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

直接運行

$ go run hello.go
Hello, world!

或者在 中嘗試一,go 命令參考

變量

var s1 string
s1 = "Learn Go!"
// 一次聲明多個變量
var b, c int = 1, 2
var d = true
// 匿名賦值(zhi)
_ , e = 10, 20 

簡短聲明

s1 := "Learn Go!"        // string
b, c := 1, 2             // int
d := true                // bool

參見:基本類型

函數

package main
import "fmt"
// 程序的入口點(dian)
func main() {
  fmt.Println("Hello world!")
  say("Hello Go!")
}
func say(message string) {
  fmt.Println("You said: ", message)
}

參見:函數(Functions)

注釋

// 單行注釋
/* 這是
多行注釋 */

if 語句

if true {
  fmt.Println("Yes!")
}

參見:條件控制

Golang 基本類型

字符串 Strings

s1 := "Hello" + "World"
s2 := `A "raw" string literal
can include line breaks.`
// 輸出:10
fmt.Println(len(s1))
// 輸(shu)出:Hello
fmt.Println(string(s1[0:5]))

字符串的類型為 字符串

數字 Numbers

num := 3             // int
num := 3.            // float64
num := 3 + 4i        // complex128
num := byte('a')     // byte (alias: uint8)
var u uint = 7       // uint (unsigned)
var p float32 = 22.7  // 32-bit float

操作符 Operators

x := 5
x++
fmt.Println("x + 4 =", x + 4)
fmt.Println("x * 4 =", x * 4) 

參見:更多操作符

布爾值 Booleans

isTrue   := true
isFalse  := false

操作符

fmt.Println(true && true)   // true 
fmt.Println(true && false)  // false
fmt.Println(true || true)   // true
fmt.Println(true || false)  // true
fmt.Println(!true)          // false

參見:更多操作符

數組 Arrays

┌────┬────┬────┬────┬─────┬─────┐
| 2  | 3  | 5  | 7  | 11  | 13  |
└────┴────┴────┴────┴─────┴─────┘
  0    1    2    3     4     5

primes := [...]int{2, 3, 5, 7, 11, 13}
fmt.Println(len(primes)) // => 6
// 輸出:[2 3 5 7 11 13]
fmt.Println(primes)
// 與 [:3] 相(xiang)同,輸(shu)出:[2 3 5]
fmt.Println(primes[0:3])

var a [2]string
a[0] = "Hello"
a[1] = "World"
fmt.Println(a[0], a[1]) //=> Hello World
fmt.Println(a)   // => [Hello World]

2d array

var twoDimension [2][3]int
for i := 0; i < 2; i++ {
    for j := 0; j < 3; j++ {
        twoDimension[i][j] = i + j
    }
}
// => 2d:  [[0 1 2] [1 2 3]]
fmt.Println("2d: ", twoDimension)

指針(Pointers)

func main () {
  b := *getPointer()
  fmt.Println("Value is", b)
}

func getPointer () (myPointer *int) {
  a := 234
  return &a
}
//申明指針(zhen)的(de)時候,如(ru)果沒有指向某個變量,默認值為nil
//不能直接(jie)進行操作,包(bao)括(kuo)讀寫
var p *int
*p = 123      // panic   nil pointer

//而用(yong)new返回的(de)是有(you)默認值的(de)指針, 為數據類型的(de)默認值
func main(){
  //有(you)一塊(kuai)內存存放了10,它的地(di)址由系統自動分配,別名是a
  a := 10
  //內存存放的10變(bian)成了20
  a = 20
  var p *int
  p = &a   //或者直接寫 p := &a
  //上面的(de)p是一個指針,通過(guo) *p 的(de)方式同(tong)樣可以訪問 變量a指向(xiang) 的(de)內存

  /*當你動態(tai)申請內(nei)存(cun)的時候,指針的存(cun)在(zai)意(yi)義之(zhi)一就(jiu)被(bei)體現(xian)出來了(le)*/ 
  ptr := new(int)   
  //申(shen)請了一塊內存空間,沒有辦法指(zhi)定別名,new()返回內存地址,用指(zhi)針接收
  //此時(shi)并沒有變(bian)量(liang)能直接(jie)指向這塊內(nei)存,所以只能通過內(nei)存地址來訪(fang)問
}

參見:

切片(Slices)

s := make([]string, 3)
s[0] = "a"
s[1] = "b"
s = append(s, "d")
s = append(s, "e", "f")
fmt.Println(s)
fmt.Println(s[1])
fmt.Println(len(s))
fmt.Println(s[1:3])
slice := []int{2, 3, 4}

另見:

常量(Constants)

const s string = "constant"
const Phi = 1.618
const n = 500000000
const d = 3e20 / n

常量(liang)聲(sheng)明可以(yi)使用(yong) iota常量(liang)生成器 初(chu)始化,它用(yong)于(yu) 生成一(yi)組以(yi)相似規則初(chu)始化的常量(liang),但是不(bu)用(yong)每行都(dou) 寫一(yi)遍初(chu)始化表(biao)達(da)式。 注意:

  1. 在一個const聲明語句中,在第一個聲明的常量所在的行,iota被置為0,然后在每一個有常量聲明的行加一。
  2. 寫在同一行的值是相同的
const (
    a = iota
    b
    c
)
// a = 0, b = 1, c = 2

類型轉換

Go語言中不(bu)允許隱式轉(zhuan)換,所有類(lei)型轉(zhuan)換必(bi)須顯式聲明(強制轉(zhuan)換),而且轉(zhuan)換只能發生(sheng)在兩種相(xiang)互(hu)兼容的類(lei)型之間。

i := 90
f := float64(i)
u := uint(i)
// 將等于字(zi)符(fu)Z
s := string(i)

如何獲取int字符串?

i := 90
// 需要導入“strconv”
s := strconv.Itoa(i)
fmt.Println(s) // Outputs: 90

Golang 字符串

字符串函數

package main
import (
        "fmt"
        s "strings"
)
func main() {
    /* 需要將字符(fu)串(chuan)導(dao)入(ru)為(wei) s */
        fmt.Println(s.Contains("test", "e"))
    /* 內置 */
    fmt.Println(len("hello"))  // => 5
    // 輸出: 101
        fmt.Println("hello"[1])
    // 輸(shu)出: e
        fmt.Println(string("hello"[1]))
}

fmt.Printf

package main
import (
        "fmt"
        "os"
)
type point struct {
        x, y int
}
func main() {
        p := point{1, 2}
        fmt.Printf("%v\n", p)                        // => {1 2}
        fmt.Printf("%+v\n", p)                       // => {x:1 y:2}
        fmt.Printf("%#v\n", p)                       // => main.point{x:1, y:2}
        fmt.Printf("%T\n", p)                        // => main.point
        fmt.Printf("%t\n", true)                     // => TRUE
        fmt.Printf("%d\n", 123)                      // => 123
        fmt.Printf("%b\n", 14)                       // => 1110
        fmt.Printf("%c\n", 33)                       // => !
        fmt.Printf("%x\n", 456)                      // => 1c8
        fmt.Printf("%f\n", 78.9)                     // => 78.9
        fmt.Printf("%e\n", 123400000.0)              // => 1.23E+08
        fmt.Printf("%E\n", 123400000.0)              // => 1.23E+08
        fmt.Printf("%s\n", "\"string\"")             // => "string"
        fmt.Printf("%q\n", "\"string\"")             // => "\"string\""
        fmt.Printf("%x\n", "hex this")               // => 6.86578E+15
        fmt.Printf("%p\n", &p)                       // => 0xc00002c040
        fmt.Printf("|%6d|%6d|\n", 12, 345)           // => |    12|   345|
        fmt.Printf("|%6.2f|%6.2f|\n", 1.2, 3.45)     // => |  1.20|  3.45|
        fmt.Printf("|%-6.2f|%-6.2f|\n", 1.2, 3.45)   // => |1.20  |3.45  |
        fmt.Printf("|%6s|%6s|\n", "foo", "b")        // => |   foo|     b|
        fmt.Printf("|%-6s|%-6s|\n", "foo", "b")      // => |foo   |b     |
        s := fmt.Sprintf("a %s", "string")
        fmt.Println(s)
        fmt.Fprintf(os.Stderr, "an %s\n", "error")
}

另見:

函數實例

實例Result
Contains("test", "es")true
Count("test", "t")2
HasPrefix("test", "te")true
HasSuffix("test", "st")true
Index("test", "e")1
Join([]string{"a", "b"}, "-")a-b
Repeat("a", 5)aaaaa
Replace("foo", "o", "0", -1)f00
Replace("foo", "o", "0", 1)f0o
Split("a-b-c-d-e", "-")[a b c d e]
ToLower("TEST")test
ToUpper("test")TEST

Golang 條件控制

有條件的

a := 10
if a > 20 {
    fmt.Println(">")
} else if a < 20 {
    fmt.Println("<")
} else {
    fmt.Println("=")
}

if 中的語句

x := "hello go!"
if count := len(x); count > 0 {
    fmt.Println("Yes")
}

if _, err := doThing(); err != nil {
    fmt.Println("Uh oh")
}

Switch

x := 42.0
switch x {
  case 0:
  case 1, 2:
      fmt.Println("Multiple matches")
  case 42:   // Don't "fall through".
      fmt.Println("reached")
  case 43:
      fmt.Println("Unreached")
  default:
      fmt.Println("Optional")
}

參見:

For loop

for i := 0; i <= 10; i++ {
  fmt.Println("i: ", i)
}

對于 Range 循環

nums := []int{2, 3, 4}
sum := 0
for _, num := range nums {
  sum += num
}
fmt.Println("sum:", sum)

For 循環

i := 1
for i <= 3 {
  fmt.Println(i)
  i++
}

Continue 關鍵字

for i := 0; i <= 5; i++ {
  if i % 2 == 0 {
      continue
  }
  fmt.Println(i)
}

Break 關鍵字

for {
  fmt.Println("loop")
  break
}

Golang 結構和Maps

定義

package main
import (
        "fmt"
)
type Vertex struct {
        X int
        Y int
}
func main() {
        v := Vertex{1, 2}
        v.X = 4
        fmt.Println(v.X, v.Y) // => 4 2
}

參見:

字面量

v := Vertex{X: 1, Y: 2}
// Field names can be omitted
v := Vertex{1, 2}
// Y is implicit
v := Vertex{X: 1}

您還可以輸入字段名

Maps

m := make(map[string]int)
m["k1"] = 7
m["k2"] = 13
fmt.Println(m) // => map[k1:7 k2:13]
v1 := m["k1"]
fmt.Println(v1)     // => 7
fmt.Println(len(m)) // => 2
delete(m, "k2")
fmt.Println(m) // => map[k1:7]
_, prs := m["k2"]
fmt.Println(prs) // => false
n := map[string]int{"foo": 1, "bar": 2}
fmt.Println(n) // => map[bar:2 foo:1]

指向結構的指針

v := &Vertex{1, 2}
v.X = 2

Doing v.X is the same as doing (*v).X, when v is a pointer.

Golang 函數

多個參數

func plus(a int, b int) int {
    return a + b
}
func plusPlus(a, b, c int) int {
    return a + b + c
}
fmt.Println(plus(1, 2))
fmt.Println(plusPlus(1, 2, 3))

多返回值

func vals() (int, int) {
  return 3, 7
}
a, b := vals()
fmt.Println(a)    // => 3
fmt.Println(b)    // => 7

匿名函數

r1, r2 := func() (string, string) {
    x := []string{"hello", "world"}
    return x[0], x[1]
}()
// => hello world
fmt.Println(r1, r2)

命名返回值

func split(sum int) (x, y int) {
  x = sum * 4 / 9
  y = sum - x
  return
}
x, y := split(17)
fmt.Println(x)   // => 7
fmt.Println(y)   // => 10

可變參數函數

func sum(nums ...int) {
  fmt.Print(nums, " ")
  total := 0
  for _, num := range nums {
      total += num
  }
  fmt.Println(total)
}
sum(1, 2)     // => [1 2] 3
sum(1, 2, 3)  // => [1 2 3] 6
nums := []int{1, 2, 3, 4}
sum(nums...)  // => [1 2 3 4] 10
// 不定參在內存中是(shi)連續(xu)存儲(chu)的(de)
// 不(bu)定參內部再(zai)傳遞的(de)時候,參數也要是不(bu)定的(de)

初始化函數

import --> const --> var --> init()

var num = setNumber()
func setNumber() int {
  return 42
}
func init() {
  num = 0
}
func main() {
  fmt.Println(num) // => 0
}

作為值的函數

func main() {
  // 將函數賦給名(ming)稱
  add := func(a, b int) int {
      return a + b
  }
  // 使用(yong)名稱調用(yong)函數
  fmt.Println(add(3, 4)) // => 7
}

閉包

func outer() (func() int, int) {
    outer_var := 2
    inner := func() int {
        outer_var += 99
        return outer_var
    }
    inner()
    return inner, outer_var
}
inner, val := outer()
fmt.Println(val)
// => 101
fmt.Println(inner())
// => 200,這里(li)涉及到(dao)golang中閉包和(he)內存逃逸的概念,inner()實際上執行了兩次(ci),outer()中一次(ci),fmt又一次(ci),
//但為什么是200呢,編(bian)譯器不(bu)能確定outer_var在后續會(hui)(hui)不(bu)會(hui)(hui)使(shi)用(yong),
//所以outer_var不(bu)會隨著(zhu)outer()結束而釋放它的棧(Stack)空間,
//而會(hui)‘逃逸到’堆(dui)(Heap)上,那么第二(er)次的inner()中outer_var就會(hui)是101。

關閉 1

func scope() func() int{
  outer_var := 2
  foo := func() int {return outer_var}
  return foo
}
// Outpus: 2
fmt.Println(scope()())

Golang 包(Packages)

導入

import "fmt"
import "math/rand"

等同于

import (
  "fmt"        // 給 fmt.Println
  "math/rand"  // 給 rand.Intn
)

另見:

別名

import r "math/rand"

import (
    "fmt"
    r "math/rand"
)

r.Intn()

Packages

package main
// 一(yi)個內(nei)部(bu)包(bao)只能被另(ling)一(yi)個包(bao)導(dao)入
// 那是在以內部目(mu)錄的父級為(wei)根的樹內
package internal

另見:

導出名稱

// 以大寫(xie)字(zi)母開頭
func Hello () {
  ···
}

另見:

Golang 并發

協程

package main
import (
    "fmt"
    "time"
)
func f(from string) {
    for i := 0; i < 3; i++ {
            fmt.Println(from, ":", i)
    }
}
func main() {
    f("direct")
    go f("goroutine")
    go func(msg string) {
            fmt.Println(msg)
    }("going")
    time.Sleep(time.Second)
    fmt.Println("done")
}

參見:,

WaitGroup

package main
import (
    "fmt"
    "sync"
    "time"
)
func w(id int, wg *sync.WaitGroup) {
    defer wg.Done()
    fmt.Printf("%d starting\n", id)
    time.Sleep(time.Second)
    fmt.Printf("%d done\n", id)
}
func main() {
    var wg sync.WaitGroup
    for i := 1; i <= 5; i++ {
            wg.Add(1)
            go w(i, &wg)
    }
    wg.Wait()
}

參見:

Closing channels

ch <- 1
ch <- 2
ch <- 3
close(ch) // 關閉(bi)頻道

// 迭代通道直到(dao)關(guan)閉
for i := range ch {
  ···
}

// Closed if `ok == false`
v, ok := <- ch

參見:

緩沖通道

ch := make(chan int, 2)
ch <- 1
ch <- 2
ch <- 3
// 致(zhi)命錯誤:
// 所有 goroutine 都處于休眠狀態 - 死鎖

參見:

Golang 錯誤控制

延遲函數

func main() {
  defer func() {
    fmt.Println("Done")
  }()
  fmt.Println("Working...")
}

Lambda defer

func main() {
  var d = int64(0)
  defer func(d *int64) {
    fmt.Printf("& %v Unix Sec\n", *d)
  }(&d)
  fmt.Print("Done ")
  d = time.Now().Unix()
}

defer 函數使用當前值d,除非我們使用指針在 main 末尾獲取最終值

Defer

func main() {
  defer fmt.Println("Done")
  fmt.Println("Working...")
}

參見:

Golang 方法(Methods)

接收器

//Go語言(yan)中(zhong)的(de)方法(Method)是一種作(zuo)用于特定(ding)類型變(bian)量的(de)函數。
//這種特定(ding)類型變量叫做接收(shou)者(Receiver)。
//接收(shou)者的概(gai)念就類似(si)于其他(ta)語言中的 this 或者 self。
//方法的定(ding)義(yi)格(ge)式(shi)如下:
func (接收者變量 接收者類型) 方法名(參數列表) (返回參數) {
    函數體(ti)
}
// 其中(zhong),
//     1.接收(shou)者(zhe)變量(liang):接收(shou)者(zhe)中的參(can)數(shu)變量(liang)名(ming)在命名(ming)時,官(guan)方建議使用接收(shou)者(zhe)類型(xing)名(ming)
//的(de)第一個小寫字(zi)母,而不是self、this之類的(de)命名。例(li)如,Person類型的(de)接(jie)收者變量
// 應該命(ming)名(ming)為 p,Connector類型的接收者變量應該命(ming)名(ming)為c等。
//     2.接(jie)收者類(lei)型(xing)(xing)(xing):接(jie)收者類(lei)型(xing)(xing)(xing)和(he)參數類(lei)似,可以是指針(zhen)類(lei)型(xing)(xing)(xing)和(he)非指針(zhen)類(lei)型(xing)(xing)(xing)。
//     3.方法名、參數列表、返回參數:具體格式與函數定義相同。
type Vertex struct {
  X, Y float64
}

func (v Vertex) Abs() float64 {
  return math.Sqrt(v.X * v.X + v.Y * v.Y)
}
func (v Vertex) valuechange() float64 {
  v.X += 1
  return v.X
}
func (v *Vertex) pointerchange() float64 {
  v.X += 1
  return v.X
}
func main() {
  v := Vertex{1, 2}
  v.Abs()

  v = Vertex{1, 2}
  fmt.Println(v.valuechange())  // 2
  fmt.Println(v)                // {1 2}

  v = Vertex{1, 2}
  fmt.Println(v.pointerchange())// 2
  fmt.Println(v)                // {2 2}
}
//如果在方法里(li)修(xiu)改receiver的(de)值要(yao)對(dui)caller生效(xiao),使用 pointer receiver。

參見:,

方法表達式

方法表達式相當于(yu)提(ti)供一(yi)種(zhong)語法將類型方法調(diao)用顯式地(di)轉換為函數調(diao)用,接收者(zhe)(receiver)必須顯式地(di)傳(chuan)遞進去。

func (t T) Get(){
    return t.a
}
func (t *T) Set(i int){
    t.a = i
}
//表(biao)達(da)式(shi)(shi)`T.Get`和`(*T).Set`被稱為方法表(biao)達(da)式(shi)(shi),
//需要注意的是在方(fang)法表達式中編譯器不會做自動(dong)轉換。
//值調用會自動轉換,表達式調用則不(bu)會,例如:
type Data struct{}
func (Data) TestValue () {}
func (*Data) TestPointer () {} 
//聲明一個類(lei)型變(bian)量a
var a Data= struct{}{}
//表達式(shi)調用編譯器不會(hui)進行(xing)自動轉(zhuan)換
Data.TestValue(a) 
//Data.TestValue(&a) 
(*Data).TestPointer (&a) 
//Data.TestPointer(&a) //type Data has no method TestPointer 
//值調用(yong)編(bian)譯器會進行自動轉換
y : = (&a).TestValue //編譯器幫(bang)助轉換a.TestValue
g : = a.TestPointer //會轉(zhuan)換為(&a).TestPointer 

組合結構的方法集

內嵌字段(duan)的(de)(de)訪問不需要(yao)使(shi)用全(quan)路徑,只要(yao)保證命名是唯(wei)一的(de)(de)就可以,盡量避免同(tong)名。如果(guo)外(wai)層(ceng)字段(duan)和內層(ceng)字段(duan)有相同(tong)的(de)(de)方法,則使(shi)用簡化模式訪問外(wai)層(ceng)方法會覆蓋內層(ceng)的(de)(de)方法。

x : = X{a: 1} 
y : = Y{ 
    X : x , 
    b : 2 , 
}
z : = z { 
    Y : y , 
    c : 3 ,
}//組合結構,內嵌字段

組合結構的方法集有如(ru)下規則:

  • 若類型 T 包含匿名字段 S ,則 T 的方法集包含S的方法集
  • 若類型 T 包含匿名字段 S ,則 T 的方法集包含 S 和S方法集
  • 不管類型 T 中嵌入的匿名字段是 S 還是 *S ,*T 方法集總是包含 S 和 *S 方法集

Golang 接口(Interfaces)

基本接口(Interfaces)

type Shape interface {
  Area() float64
  Perimeter() float64
}

結構(Struct)

type Rectangle struct {
  Length, Width float64
}

結構 Rectangle 通過實現其所有方法隱式實現接口 Shape

方法(Methods)

func (r Rectangle) Area() float64 {
  return r.Length * r.Width
}
func (r Rectangle) Perimeter() float64 {
  return 2 * (r.Length + r.Width)
}

Shape 中定義的方法在Rectangle中實現

接口實例

func main() {
  var r Shape = Rectangle{Length: 3, Width: 4}
  fmt.Printf("Type of r: %T, Area: %v, Perimeter: %v.", r, r.Area(), r.Perimeter())
}

雜項

關鍵字(Keywords)

  • 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

運算符和標點符號

+&+=&=&&==!=()
-|-=|=||<<=[]
*^*=^=<->>={}
/<</=<<=++=:=,;
%>>%=>>=--!....:
&^&^=

Go 命令

Go 編譯器命令

:---
go command [參數]go 命令 [參數]
go build編譯包和依賴包
go clean移除對象和緩存文件
go doc顯示包的文檔
go env打印go的環境變量信息
go bug報告bug
go fix更新包使用新的api
go fmt格式規范化代碼
go generate通過處理資源生成go文件
go get下載并安裝包及其依賴
go install編譯和安裝包及其依賴
go list列出所有包
go run編譯和運行go程序
go test測試
go tool運行給定的go工具
go version顯示go當前版本
go vet發現代碼中可能的錯誤

ENV

:---
GOOS編譯系統
GOARCH編譯arch
GO111MODULEgomod開關
GOPROXYgo代理
GOSSAFUNC生成 SSA.html 文件,展示代碼優化的每一步 GOSSAFUNC=func_name go build

Module

:---
go mod init初始化當前文件夾,創建go.mod文件
go mod download下載依賴的module到本地
go mod tidy增加缺少的module,刪除無用的module
go mod vendor將依賴復制到vendor下
文件 go.mod依賴列表和版本約束
文件 go.sum記錄 module 文件 hash 值,用于安全校驗

另見

  • (devhints.io)
  • (tour.golang.org)
  • (github.com)
  • (golang.org)
  • (gobyexample.com)
  • (awesome-go.com)
  • (youtube.com)
  • (github.com)