go語言入門經典

Go 谷歌新語言 不損失應用程序性能的狀況降低低代碼複雜性 具備部署簡單 併發性好 語言設計良好 執行性能好的優點git

對類C語言的重大改進 可以訪問底層操做系統,還提供了強大的網絡編程和併發編程支持。
經常使用於github

  • 網絡編程
  • 系統編程
  • 併發編程
  • 分佈式編程

go語言是一門現代編程語言 可用來建立性能卓越的web服務器和系統程序。golang

go是編譯型語言web

go version
go version go1.15.1 darwin/amd64

go環境配置編程

mac@macdeMacBook-Pro ~ % mkdir $HOME/go
mac@macdeMacBook-Pro ~ % mkdir $HOME/go/bin
mac@macdeMacBook-Pro ~ % mkdir $HOME/go/pkg
mac@macdeMacBook-Pro ~ % mkdir $HOME/go/src
export GOPATH=$HOME/go

使用GitHub分享代碼
mkdir -p $GOPATH/src/github.com/199305a
go hello world數組

package main
import (
    "fmt"
)
func main() {
    fmt.Printf("hello wprld")
}

運行helloworld
go run main.go瀏覽器

go的類型服務器

go是一種靜態類型語言。

數據類型是一種重要的編程計算結構網絡

布爾類型併發

var b bool

數值
var i int = 3
浮點數
var f float32 = 0.111
字符串
var s string = "foo"
數組
var beatles [4]string
類型檢查

reflect.TypeOf(s)

類型轉換

strconv.FormatBool(b)

變量
var s string = "foo"
快捷聲明變量

var s,t string = "foo","bar"
    var (
        x string = "x"
        y int = 4
    )

變量聲明時未賦值使用 默認零值
簡短聲明變量
s := "hello world"
不能在函數外面使用簡短變量聲明
一般在函數外使用省略類型聲明方式
在函數內使用簡短變量聲明

理解變量做用域
使用指針 &s

s,t  := "foo","bar"
     fmt.Println(&s,t)

指針傳遞 打印指針內容 *x

func showMemoryAddress(x *string)  {
    fmt.Println(x);
    fmt.Println(*x);
}

聲明常量 const

const  greeting string  = "hello world"

使用函數

函數是接受輸入並返回輸出
func addUp(x int,y int) int {
    return  x + y
}

返回多個值

func getPrize() (int, string) {
    i := 2
    s := "goldfish"
    return i, s
}

定義不定參數函數 可以使用3個點
使用具名返回值

func sayHi()(x,y string)  {
    x = "hello"
    y = "world"
    return 
}

使用遞歸函數

將函數做爲值傳遞

func  anotherFunction(f func() string) string  {
    return  f()
}

func main() {
    fn := func() string {
        return "function called"
    }
    fmt.Println(anotherFunction(fn))
}

控制流程 if else elseif
使用if語句

func  test()  {
    b := false
    if b {
        fmt.Println("b is true")
    }
}

使用else語句 else if
使用比較運算符
== != >= <= > <
使用算術運算符
+ - * / %
使用邏輯運算符
&& || !
使用 switch 語句

func test1() {
    i := 2
    switch i {
    case 1:
        fmt.Println("One")
    case 2:
        fmt.Println("Two")
    case 3:
        fmt.Println("Three")
     default:   
    }
}

使用for循環 range

func test2() {
    i := 0
    for i < 10 {
        fmt.Println("i is", i)
        i++

    }
    for i := 0; i < 10; i++ {
        fmt.Println("i is", i)
    }
    numbers := []int{1, 2, 3, 4}
    for i, n := range numbers {
        fmt.Println("The index of the loop is", i)
        fmt.Println("The value from the array is", n)
    }
}

使用 defer語句 多條語句倒序執行

func test3()  {
    defer  fmt.Println("i am run after the func complete")
    fmt.Println("hello world")
}
hello world
i am run after the func complete

數組 切片和映射
使用數組 長度固定
var cheese [2]string
使用切片 更加靈活

var cheese = make([]string,2)

在切片添加元素 append
從切片中刪除元素 刪除索引2處的元素

append(cheese[:2],cheese[2+1:]...)

複製切片中的元素

copy(cheese,cheeses[1:])

使用映射

func test5()  {
    var players = make(map[string]int)
    players["cook"] = 32
    players["bairstow"] = 27
    players["stokes"] = 26
    fmt.Println(players["cook"])
}

從映射中刪除元素

delete(players,"stokes")

結構體是什麼

結構體是一系列具備指定數據類型的數據字段
type Movie struct {
    Name string
    Rating float32
}

func test6()  {
     m := Movie{
         Name:   "Citizen Kane",
         Rating: 10,
     }
     fmt.Println(m)
}

嵌套結構體

自定義結構體數據字段的默認值
比較結構體 若是結構體類型不一樣 將會出現編譯錯誤

理解公有和私有值
私有值只能在其所屬上下文中使用
要導出結構體及其字段 字段名稱必須以大寫字母開頭

區分指針引用和值引用
結構體是值引用
變爲指針引用

n := &m

建立方法和接口
使用方法 附加在實例上

func (m * Movie) summary() string  {
    
}
m.summary()

建立方法集

使用方法和指針

package main

import "fmt"

type Triangle struct {
    base float64
    height float64
}

func (t * Triangle) changeBase(f float64)  {
    t.base = f
    return
}

func main() {
  t := Triangle{base:3,height:1}
  t.changeBase(4)
  fmt.Println(t.base)
}

使用接口

type Robot interface {
    PowerOn() error
}

type  R2D2 struct {
    Broken bool
}

func (r * R2D2) PowerOn() error {
    if r.Broken {
        return  errors.New("R2D2 is broken")
    }else  {
        return nil
    }
}

使用字符串
字符串字面量

s := "I am an interpreted string Literal"

rune字面量
`
s := "I am an interpretedn string Literal"
`
拼接字符串 使用運算符+

s1 :="Oh sweet ignition" + "be my fuse"
intToString := strconv.Itoa(i1)

使用緩衝區拼接字符串

var buffer bytes.Buffer
    for i :=0;    i < 500;i++  {
        buffer.WriteString("z")
    }
    fmt.Println(buffer)

字符串 字節切片
處理字符串
將字符串轉換爲小寫

fmt.Println(strings.ToLower("VERY BEAUTIFUL"))

在字符串中查找子串

fmt.Println(strings.Index("VERY surface","face"))

刪除字符串首位的空格

fmt.Println(strings.TrimSpace("VERY BEAUTIFUL"))

處理錯誤
錯誤處理及Go語言的獨特之處

file,err := ioutil.ReadFile("foo.txt")
    if err != nil{
         fmt.Println(err)
        return
    }
    fmt.Println("%s",file)

理解錯誤類型
建立錯誤

err := errors.New("Something went wrong")
    if err != nil {
         fmt.Println(err)
    }

從函數返回錯誤

func Half(numberToHalf int) (int, error) {
    if numberToHalf%2 != 0 {
        return -1, fmt.Errorf("Cannot half %v", numberToHalf)
    }
    return numberToHalf / 2, nil
}

錯誤和可用性
慎用 panic 會終止程序

使用Goroutine 併發
理解併發
併發和並行 併發 多個任務同時執行
並行 任務分紅多個部分進行執行

併發就是同時處理不少事情 並行就是同時作不少事情

經過web瀏覽器來理解併發
阻塞和非阻塞代碼

time.Sleep(time.Second * 2)

使用Goroutine處理併發操做
函數前添加go 來是函數異步執行

go    test6()

通道簡介
使用通道

func slowFunc(c chan string)  {

    time.Sleep(time.Second * 2)
    c <- "slowFunc() finished"

}
func test1()  {
    c :=make(chan  string)
    go slowFunc(c)
    msg := <-c
    fmt.Println(msg)
}

使用緩衝通道 指定通道數量 最後close通道

func slowFunc(c chan string)  {

    time.Sleep(time.Second * 2)
    c <- "slowFunc() finished1"
    c <- "slowFunc() finished2"

}
func test1()  {
    c :=make(chan  string,2)
    go slowFunc(c)
    msg1 := <-c
    msg2 := <-c
    close(c)
    fmt.Println(msg1,msg2)
}

阻塞和流程控制
使用for阻塞流程

func slowFunc(c chan string)  {
  t := time.NewTicker(1 * time.Second)
    for  {
        c <- "ping"
        <-t.C
    }
}
func test2()  {
    message := make(chan string)
    go slowFunc(message)
    for {
        msg := <-message
        fmt.Println(msg)
    }
}

將通道用做函數參數
<- 位於chan左邊 表示制度 位於右邊 表示只寫

使用select語句 當接收到一條數據時 將再也不阻塞

func test3() {
    channel1 := make(chan string)
    channel2 := make(chan string)
    select {
    case msg1 := <-channel1:
        fmt.Println("received", msg1)
    case msg2 := <-channel2:
        fmt.Println("received", msg2)
    }
}

退出通道
case <- stop

func sender(c chan string)  {
    t := time.NewTicker(1 * time.Second)
    for {
        c <- "I a messgae"
        <-t.C
    }
}

func test1()  {
    messages := make(chan string)
    stop := make(chan  bool)
    go sender(messages)
    go func() {
        time.Sleep(time.Second * 2)
        fmt.Println("Time is up")
        stop <- true
    }()
    for  {
        select {
        case <-stop:
            return
        case msg := <-messages:
            fmt.Println(msg)

        }
    }
}

使用包實現代碼重用
導入包

import (
    "fmt"
    "time"
)

使用第三方包
go get github.com/golang/example/stringutil

func test2()  {
    s := "ti ercesxsc"
    fmt.Println(stringutil.Reverse(s))
}

管理第三方依賴
go get u all

GO111MODULE=auto
go run hello.go

建立包

package temperature

func CtoF(c float64)float64 {
    return (c * (9 / 5)) + 32
}
func FtoC(c float64)float64 {
    return (c - 32) * (9 / 5)
}

Go語言命名約定
Go代碼格式設置
使用gofmt
gofmt temperature.go
gofmt -w temperature.go

配置文本編輯器

相關文章
相關標籤/搜索