Go語言第一天

內容介紹

  • Go語言簡述

  • Go語言站點

  • Go基礎環境搭建(linux&windows)

  • hello word程序

  • Go語言特性

  • Go命令介紹

Go語言簡述

  • 特徵:

    • 語法簡單:語法標準比較嚴格,適合開發人員短時間高效的服務端開發。

    • 併發模型:Goroutine是Go最顯著的特徵,使用類協程的方式來處理併發,搭載channel實現CSP模型

    • 內存分配:Go選擇tcmaclloc來實現高併發的內存管理和分配

    • 垃圾回收:防止出現OOM的坑

    • 靜態鏈接:簡化了部署和發佈操作,極大程度上降低了代碼發佈的依賴關係

    • 標準庫:功能完善的標準庫,有利於降低學習成本

    • 工具鏈:無論是編譯,格式化,錯誤檢查,幫助文檔和對應的測試支持都比較完善

  • 總結:

      go語言作爲一個現代化的開發語言,利用其高併發的特性,有利於實現服務端開發;再結合自身的語法規範性上,可以更好的爲API的開發提供更好的幫助;作爲一種編譯性開發語言。在web開發方面還存在着一定的高效性差距;然而在通過同步方式封裝異步概念來更好的處理併發,所以更適合現在的服務端開發。

Go語言站點

官方站點:https://golang.org/dl/

官方站現在不能訪問,提供如下的下載站點:https://golangtc.com/static/go/1.9.2/go1.9.2.linux-amd64.tar.gz

開發IDE鏈接:http://www.jetbrains.com/go/golang.com/d

Go語言環境搭建

Linux下配置Go

  • 下載對應的:go1.9.2.linux-amd64.tar.gz

  • 解壓文件tar xf go1.9.2.linux-amd64.tar.gz –C /usr/local

  • 設置環境變量

 

root#vim /etc/profile
export GOROOT=$PATH:/path/to/go/
export PATH=$PATH:$GOROOT/bin/
export GOPATH=/home/user/project/go
root# source /etc/profile

window下安裝Go

  • 下載好對應的安裝包:go1.9.2.windows-amd64.msi

  • 雙擊安裝

  • IDE下載:http://www.jetbrains.com/go/

  • 安裝IDE

  • 測試環境變量,打開cmd命令行,輸入go env即可顯示環境變量

 

C:\Users\wanghui>go  env
set GOARCH=amd64
set GOBIN=
set GOEXE=.exe
set GOHOSTARCH=amd64
set GOHOSTOS=windows
set GOOS=windows
set GOPATH=E:\project\       #項目環境變量,一個項目有且僅有這一個配置變量,不然會導致環境混亂;設置方式需要在windows上添加此項配置
set GORACE=
set GOROOT=D:\MyDevSoftInstallDir\Go
set GOTOOLDIR=D:\MyDevSoftInstallDir\Go\pkg\tool\windows_amd64
set GCCGO=gccgo
set CC=gcc
set GOGCCFLAGS=-m64 -mthreads -fmessage-length=0
set CXX=g++
set CGO_ENABLED=1
set CGO_CFLAGS=-g -O2
set CGO_CPPFLAGS=
set CGO_CXXFLAGS=-g -O2
set CGO_FFLAGS=-g -O2
set CGO_LDFLAGS=-g -O2
set PKG_CONFIG=pkg-config

hello world程序

  • 創建項目路徑並且配置GOPATH環境變量,我在電腦E盤下創建了一個文件夾,名稱是project,作爲項目的GOPATH

  • 打開IDE,選擇好對應的項目路徑並打開

創建如下的目錄結構:

hello.go代碼如下:

 

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

運行代碼:go run hello.go

工作區介紹

  • GOPATH

    • 所有的項目都要放到$GOPATH/src

    • GOPATH的路徑最好配置一個

    • 注意要有良好的目錄結構

基本命令介紹

首先建立如下的目錄結構:

 

├─program
│    └─src
|       └─code.oldboy.com
│            └─day1

所有的項目就從day1的同一級目錄開始,咱們先寫一個求和求差的小程序:

  • day1/calc/Calc.go

package calc
//求和
func Add(a int,b int) int {
    return a + b
}
//求差
func Sub(a int,b int) int {
    return a - b
}
//多返回值混合運算
func Calc(a int,b int) (int,int) {
    sum := a + b
    sub := a - b
    return sum,sub
}
  • da1/hello/hello2.go

 

package main
//導入模塊
import (
    "code.oldboy.com/day1/calc"
    "fmt"
)
//main入口函數
func main() {
    //定義變量給單個retun的Add和Sub使用
    var sum int
    var sub int
    sum = calc.Add(100,200)
    sub = calc.Sub(300,10)
    //定義變量給多個返回值的Calc函數使用
    sum_1,sub_1 := calc.Calc(100,50)
    fmt.Println(sum,sub)
    //格式化打印結果
    fmt.Printf("muti return sum is %d,sub is %d ",sum_1,sub_1)
}

go run

在CMD終端執行

 

E:\>cd program
E:\program>cd src
E:\program\src>cd code.oldboy.com
E:\program\src\code.oldboy.com>cd day1
E:\program\src\code.oldboy.com\day1>cd hello
E:\program\src\code.oldboy.com\day1\hello>go run hello.go
hello word!!
E:\program\src\code.oldboy.com\day1\hello>go run hello2.go
300 290
muti return sum is 150,sub is 50

go run 運行的入口文件   這樣就能夠不需要編譯直接執行,不需要考慮到依賴關係,可以理解成自動編譯執行。

go build 

這個操作就是要進行編譯程序,然後根據操作平臺,指定生成一個可執行程序。同樣也是解決了依賴,直接就執行就好。

 

E:\>cd program
E:\program>go build -o bin/Hello2.exe code.oldboy.com/day1/hello     #編譯程序
E:\program>cd bin
E:\program\bin>Hello2.exe     #執行生成的文件
300 290
muti return sum is 150,sub is 50

go install

go install會依次查找所有GOPATH中的目錄尋找hello包和它依賴的code.oldboy.com/day1/hello包。然後會將報名爲main的包生成二進制文件放到GOBIN目錄下。將非main包編譯成.a文件放到項目對於的pkg目錄下

 

E:\program>go install code.oldboy.com/day1/hello
E:\program>cd pkg
E:\program\pkg>dir
2017/11/29  16:17    <DIR>          .
2017/11/29  16:17    <DIR>          ..
2017/11/29  16:17    <DIR>          windows_amd64
E:\program\pkg>cd windows_amd64
E:\program\pkg\windows_amd64>dir
2017/11/29  16:17    <DIR>          .
2017/11/29  16:17    <DIR>          ..
2017/11/29  16:17    <DIR>          code.oldboy.com
E:\program\pkg\windows_amd64>tree
文件夾 PATH 列表
卷序列號爲 704D-FB7A
E:.
└─code.oldboy.com
    └─day1
E:\program\pkg\windows_amd64>cd code.oldboy.com/
E:\program\pkg\windows_amd64\code.oldboy.com>cd day1
E:\program\pkg\windows_amd64\code.oldboy.com\day1>dir
E:\program\pkg\windows_amd64\code.oldboy.com\day1 的目錄
2017/11/29  16:17    <DIR>          .
2017/11/29  16:17    <DIR>          ..
2017/11/29  16:17             1,694 calc.a

go test

go test是執行單元測試或者壓力測試

下面就是一個測試樣例,代碼如下:

  • code.oldboy.com/day1/calc/test/calc_test.go

 

package test
//導入測試包
import(
    "testing"
    "code.oldboy.com/day1/calc"
)
//測試函數
func TestAdd(t *testing.T){
    var sum int
    sum = calc.Add(5,6)
    if sum != 11{
        t.Fatalf("add is not correct,sum:%v expected 11",sum)
    }
    t.Logf("add is ok!")
}
func TestSub(t *testing.T){
    var sub int
    sub = calc.Sub(5,6)
    if sub != -1 {
        t.Fatalf("sub is not right,sub:%v -1",sub)
    }
    t.Logf("sub is ok!!")
}

執行測試:

 

E:\program>cd src
E:\program\src>cd code.oldboy.com
E:\program\src\code.oldboy.com>cd day1
E:\program\src\code.oldboy.com\day1>cd calc
E:\program\src\code.oldboy.com\day1\calc>cd test
E:\program\src\code.oldboy.com\day1\calc\test>go test calc_test.go
ok      command-line-arguments  1.399s

go env

顯示環境變量

cmd下執行

 

E:\program>go env
set GOARCH=amd64
set GOBIN=
set GOEXE=.exe
set GOHOSTARCH=amd64
set GOHOSTOS=windows
set GOOS=windows
set GOPATH=E:\program
set GORACE=
set GOROOT=D:\Program Files (x86)\Go
set GOTOOLDIR=D:\Program Files (x86)\Go\pkg\tool\windows_amd64
set GCCGO=gccgo
set CC=gcc
set GOGCCFLAGS=-m64 -mthreads -fmessage-length=0
set CXX=g++
set CGO_ENABLED=1
set CGO_CFLAGS=-g -O2
set CGO_CPPFLAGS=
set CGO_CXXFLAGS=-g -O2
set CGO_FFLAGS=-g -O2
set CGO_LDFLAGS=-g -O2
set PKG_CONFIG=pkg-config

go fmt

格式化代碼,以便統一代碼風格。

 

#單個文件格式化
E:\program>cd src
E:\program\src>cd code.oldboy.com
E:\program\src\code.oldboy.com>cd day1
E:\program\src\code.oldboy.com\day1>cd hello
E:\program\src\code.oldboy.com\day1\hello>go fmt hello2.go  #單個文件格式化
hello2.go
#所有項目全部格式化
E:\program>gofmt -w -l src
src\code.oldboy.com\day1\calc\calc.go
src\code.oldboy.com\day1\calc\test\calc_test.go
src\home_exe\calc\calc.go

go程序結構

  • go源碼按照package進行組織,並且package要放到非註釋行的第一行

    • package

  • 一個程序只能有一個main包和一個main函數

  • main函數是程序的執行入口

  • 註釋:

 

//這是單行註釋
--------分界線---------
/*這是
多行
註釋*/

go語言特性

  • 垃圾回收

    • 內存自動回收,不需要人工干預

    • 開發人員專注業務實現,降低了心智負擔

    • 只需要new分配內存,不需要釋放

  • 天然併發

    • 從語言層面支持併發,非常簡單

    • goroutine輕量級線程,是的創建上萬個goroute成爲可能

    • 基於CSP模型實現

    • 下面就是一個打印技術和偶數的例子src/oldboy.com/day1/threads/main.go

 

package main
import (
    "fmt"
    "time"
)
func PrintOdd(n int){
    for i := 0; i < n; i++{
        if i % 2 == 1 {
            fmt.Printf("Odd is %d", i)
        }
    }
}
func PrintEven(n int){
    for i := 0; i < n ;i++{
        if i % 2 == 0 {
            fmt.Printf("Even is %d",i)
        }
    }
}

func main() {
    go PrintOdd(100)
    go PrintEven(100)
    time.Sleep(10*time.Second)
}

執行結果如下:

 

E:\program>go build -o bin/threads.exe code.oldboy.com/day1/threads
E:\program>cd bin
E:\program\bin>threads.exe
Odd is 1Odd is 3Odd is 5Odd is 7Odd is 9Odd is 11Odd is 13Odd is 15Odd is 17Odd
is 19Odd is 21Odd is 23Odd is 25Odd is 27Odd is 29Odd is 31Odd is 33Odd is 35Odd
 is 37Odd is 39Odd is 41Odd is 43Odd is 45Odd is 47Odd is 49Odd is 51Odd is 53Od
d is 55Odd is 57Odd is 59Odd is 61Odd is 63Odd is 65Odd is 67Odd is 69Odd is 71O
dd is 73Odd is 75Odd is 77Odd is 79Odd is 81Odd is 83Odd is 85Odd is 87Odd is 89
Odd is 91Odd is 93Odd is 95Odd is 97Odd is 99Even is 0Even is 2Even is 4Even is
6Even is 8Even is 10Even is 12Even is 14Even is 16Even is 18Even is 20Even is 22
Even is 24Even is 26Even is 28Even is 30Even is 32Even is 34Even is 36Even is 38
Even is 40Even is 42Even is 44Even is 46Even is 48Even is 50Even is 52Even is 54
Even is 56Even is 58Even is 60Even is 62Even is 64Even is 66Even is 68Even is 70
Even is 72Even is 74Even is 76Even is 78Even is 80Even is 82Even is 84Even is 86
Even is 88Even is 90Even is 92Even is 94Even is 96Even is 98
  • channel

    • 管道,類似unix中的pipe

    • 多個goroute之間通過channel進行通信

    • 支持任何類型的數據傳輸

    • 下面是個小例子:src/oldboy.com/day1/pipe/main.go

 

package main
import "fmt"
func main(){
    //創建channel
    pipe := make(chan string,3)
    //插入值
    pipe <- "a"
    pipe <- "b"
    pipe <- "c"
    //取出值
    var a1 string
    a1 =<- pipe
    fmt.Printf("%s",a1)
}

執行出來的結果如下:

  • 多個返回值,可以參考calc/Calc.go

 

//多返回值混合運算
func Calc(a int,b int) (int,int) {
    sum := a + b
    sub := a - b
    return sum,sub
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章