国产成人精品999视频&日本一区二区亚洲人妻精品&久久久精品国产99久久精&99热这里只有成人精品国产&精品国产剧情av一区二区&成人亚洲精品久久久久app&国产精品美女高潮抽搐A片

Golang 備忘清單

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

入門

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

直接運(yùn)行

$ go run hello.go
Hello, world!

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

變量

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

簡(jiǎn)短聲明

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

參見:基本類型

函數(shù)

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

參見:函數(shù)(Functions)

注釋

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

if 語(yǔ)句

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

參見:條件控制

Golang 基本類型

字符串 Strings

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

字符串的類型為 字符串

數(shù)字 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

參見:更多操作符

數(shù)組 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] 相同,輸出:[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
}
//申明指針的時(shí)候,如果沒有指向某個(gè)變量,默認(rèn)值為nil
//不能直接進(jìn)行操作,包括讀寫
var p *int
*p = 123      // panic   nil pointer

//而用new返回的是有默認(rèn)值的指針, 為數(shù)據(jù)類型的默認(rèn)值
func main(){
  //有一塊內(nèi)存存放了10,它的地址由系統(tǒng)自動(dòng)分配,別名是a
  a := 10
  //內(nèi)存存放的10變成了20
  a = 20
  var p *int
  p = &a   //或者直接寫 p := &a
  //上面的p是一個(gè)指針,通過 *p 的方式同樣可以訪問 變量a指向 的內(nèi)存

  /*當(dāng)你動(dòng)態(tài)申請(qǐng)內(nèi)存的時(shí)候,指針的存在意義之一就被體現(xiàn)出來了*/ 
  ptr := new(int)   
  //申請(qǐng)了一塊內(nèi)存空間,沒有辦法指定別名,new()返回內(nèi)存地址,用指針接收
  //此時(shí)并沒有變量能直接指向這塊內(nèi)存,所以只能通過內(nèi)存地址來訪問
}

參見:指針(Pointers)

切片(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

常量聲明可以使用 iota常量生成器 初始化,它用于 生成一組以相似規(guī)則初始化的常量,但是不用每行都 寫一遍初始化表達(dá)式。 注意:

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

類型轉(zhuǎn)換

Go語(yǔ)言中不允許隱式轉(zhuǎn)換,所有類型轉(zhuǎn)換必須顯式聲明(強(qiáng)制轉(zhuǎn)換),而且轉(zhuǎn)換只能發(fā)生在兩種相互兼容的類型之間。

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

如何獲取int字符串?

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

Golang 字符串

字符串函數(shù)

package main
import (
        "fmt"
        s "strings"
)
func main() {
    /* 需要將字符串導(dǎo)入為 s */
        fmt.Println(s.Contains("test", "e"))
    /* 內(nèi)置 */
    fmt.Println(len("hello"))  // => 5
    // 輸出: 101
        fmt.Println("hello"[1])
    // 輸出: 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")
}

另見:fmt

函數(shù)實(shí)例

實(shí)例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 中的語(yǔ)句

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")
}

參見:Switch

For loop

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

對(duì)于 Range 循環(huán)

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

For 循環(huán)

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

Continue 關(guān)鍵字

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

Break 關(guān)鍵字

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

Golang 結(jié)構(gòu)和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
}

參見:結(jié)構(gòu)(Structs)

字面量

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]

指向結(jié)構(gòu)的指針

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

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

Golang 函數(shù)

多個(gè)參數(shù)

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

匿名函數(shù)

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

可變參數(shù)函數(shù)

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
// 不定參在內(nèi)存中是連續(xù)存儲(chǔ)的
// 不定參內(nèi)部再傳遞的時(shí)候,參數(shù)也要是不定的

初始化函數(shù)

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

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

作為值的函數(shù)

func main() {
  // 將函數(shù)賦給名稱
  add := func(a, b int) int {
      return a + b
  }
  // 使用名稱調(diào)用函數(shù)
  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,這里涉及到golang中閉包和內(nèi)存逃逸的概念,inner()實(shí)際上執(zhí)行了兩次,outer()中一次,fmt又一次,
//但為什么是200呢,編譯器不能確定outer_var在后續(xù)會(huì)不會(huì)使用,
//所以outer_var不會(huì)隨著outer()結(jié)束而釋放它的棧(Stack)空間,
//而會(huì)‘逃逸到’堆(Heap)上,那么第二次的inner()中outer_var就會(huì)是101。

關(guān)閉 1

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

Golang 包(Packages)

導(dǎo)入

import "fmt"
import "math/rand"

等同于

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

另見:導(dǎo)入

別名

import r "math/rand"

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

r.Intn()

Packages

package main
// 一個(gè)內(nèi)部包只能被另一個(gè)包導(dǎo)入
// 那是在以內(nèi)部目錄的父級(jí)為根的樹內(nèi)
package internal

另見:內(nèi)部包

導(dǎo)出名稱

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

另見:導(dǎo)出的名稱

Golang 并發(fā)

協(xié)程

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")
}

參見:Goroutines, Channels

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()
}

參見:WaitGroup

Closing channels

ch <- 1
ch <- 2
ch <- 3
close(ch) // 關(guān)閉頻道

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

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

參見:范圍和關(guān)閉

緩沖通道

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

參見:緩沖通道

Golang 錯(cuò)誤控制

延遲函數(shù)

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 函數(shù)使用當(dāng)前值d,除非我們使用指針在 main 末尾獲取最終值

Defer

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

參見:Defer, panic and recover

Golang 方法(Methods)

接收器

//Go語(yǔ)言中的方法(Method)是一種作用于特定類型變量的函數(shù)。
//這種特定類型變量叫做接收者(Receiver)。
//接收者的概念就類似于其他語(yǔ)言中的 this 或者 self。
//方法的定義格式如下:
func (接收者變量 接收者類型) 方法名(參數(shù)列表) (返回參數(shù)) {
    函數(shù)體
}
// 其中,
//     1.接收者變量:接收者中的參數(shù)變量名在命名時(shí),官方建議使用接收者類型名
//的第一個(gè)小寫字母,而不是self、this之類的命名。例如,Person類型的接收者變量
// 應(yīng)該命名為 p,Connector類型的接收者變量應(yīng)該命名為c等。
//     2.接收者類型:接收者類型和參數(shù)類似,可以是指針類型和非指針類型。
//     3.方法名、參數(shù)列表、返回參數(shù):具體格式與函數(shù)定義相同。
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}
}
//如果在方法里修改receiver的值要對(duì)caller生效,使用 pointer receiver。

參見:Methods指針接收器

方法表達(dá)式

方法表達(dá)式相當(dāng)于提供一種語(yǔ)法將類型方法調(diào)用顯式地轉(zhuǎn)換為函數(shù)調(diào)用,接收者(receiver)必須顯式地傳遞進(jìn)去。

func (t T) Get(){
    return t.a
}
func (t *T) Set(i int){
    t.a = i
}
//表達(dá)式`T.Get`和`(*T).Set`被稱為方法表達(dá)式,
//需要注意的是在方法表達(dá)式中編譯器不會(huì)做自動(dòng)轉(zhuǎn)換。
//值調(diào)用會(huì)自動(dòng)轉(zhuǎn)換,表達(dá)式調(diào)用則不會(huì),例如:
type Data struct{}
func (Data) TestValue () {}
func (*Data) TestPointer () {} 
//聲明一個(gè)類型變量a
var a Data= struct{}{}
//表達(dá)式調(diào)用編譯器不會(huì)進(jìn)行自動(dòng)轉(zhuǎn)換
Data.TestValue(a) 
//Data.TestValue(&a) 
(*Data).TestPointer (&a) 
//Data.TestPointer(&a) //type Data has no method TestPointer 
//值調(diào)用編譯器會(huì)進(jìn)行自動(dòng)轉(zhuǎn)換
y : = (&a).TestValue //編譯器幫助轉(zhuǎn)換a.TestValue
g : = a.TestPointer //會(huì)轉(zhuǎn)換為(&a).TestPointer 

組合結(jié)構(gòu)的方法集

內(nèi)嵌字段的訪問不需要使用全路徑,只要保證命名是唯一的就可以,盡量避免同名。如果外層字段和內(nèi)層字段有相同的方法,則使用簡(jiǎn)化模式訪問外層方法會(huì)覆蓋內(nèi)層的方法。

x : = X{a: 1} 
y : = Y{ 
    X : x , 
    b : 2 , 
}
z : = z { 
    Y : y , 
    c : 3 ,
}//組合結(jié)構(gòu),內(nèi)嵌字段

組合結(jié)構(gòu)的方法集有如下規(guī)則:

  • 若類型 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
}

結(jié)構(gòu)(Struct)

type Rectangle struct {
  Length, Width float64
}

結(jié)構(gòu) Rectangle 通過實(shí)現(xiàn)其所有方法隱式實(shí)現(xiàn)接口 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中實(shí)現(xiàn)

接口實(shí)例

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())
}

雜項(xiàng)

關(guān)鍵字(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

運(yùn)算符和標(biāo)點(diǎn)符號(hào)

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

Go 命令

Go 編譯器命令

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

ENV

:---
GOOS編譯系統(tǒng)
GOARCH編譯arch
GO111MODULEgomod開關(guān)
GOPROXYgo代理 https://goproxy.io https://goproxy.cn https://mirrors.aliyun.com/goproxy/
GOSSAFUNC生成 SSA.html 文件,展示代碼優(yōu)化的每一步 GOSSAFUNC=func_name go build

Module

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

另見