真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

Go語言1

開發(fā)環(huán)境搭建

隨便學(xué)學(xué),平時用的都是WIndows10的操作系統(tǒng),就在這下面搞了。

我們一直強調(diào)成都網(wǎng)站制作、成都網(wǎng)站設(shè)計、外貿(mào)營銷網(wǎng)站建設(shè)對于企業(yè)的重要性,如果您也覺得重要,那么就需要我們慎重對待,選擇一個安全靠譜的網(wǎng)站建設(shè)公司,企業(yè)網(wǎng)站我們建議是要么不做,要么就做好,讓網(wǎng)站能真正成為企業(yè)發(fā)展過程中的有力推手。專業(yè)網(wǎng)站建設(shè)公司不一定是大公司,成都創(chuàng)新互聯(lián)作為專業(yè)的網(wǎng)絡(luò)公司選擇我們就是放心。

下載安裝

下載go安裝程序,下載地址:https://golang.org/dl/ (被墻了,打不開)
墻內(nèi)下載地址http://www.golangtc.com/download
我下的是這個:go1.9.2.windows-amd64.msi
安裝就下一步就好了,裝完之后驗證一下。默認已經(jīng)把Go的路徑加到環(huán)境變量中去了,所以可以直接在cmd中輸入go命令執(zhí)行:
Go語言1

環(huán)境變量

裝完之后,我裝到了D:\Go\,已經(jīng)幫我們添加好了2個環(huán)境變量:

  • GOROOT: D:\Go\
  • Path: D:\Go\bin
  • GOPATH: 這個環(huán)境變量也要,但是需要手動設(shè)置

GOPATH也是要的,設(shè)置工作區(qū)路徑,不過如果沒有設(shè)置的話,有一個默認位置(差不多就是系統(tǒng)的家目錄)。執(zhí)行幫助命令 go help gopath ,我這截了一段說明:

If the environment variable is unset, GOPATH defaults
to a subdirectory named "go" in the user's home directory
($HOME/go on Unix, %USERPROFILE%\go on Windows),
unless that directory holds a Go distribution.
Run "go env GOPATH" to see the current GOPATH.

暫時不設(shè)置也沒影響,反正也有默認的,后面寫 Hellow World 的時候再看設(shè)置在哪個目錄

開發(fā)工具

開發(fā)工具先沒有裝,不過這里先記一下工具的名稱:

Visual Studio Code (簡稱 VS Code / VSC) 是一款免費開源的現(xiàn)代化輕量級代碼編輯器,支持幾乎所有主流的開發(fā)語言的語法高亮、智能代碼補全、自定義熱鍵、括號匹配、代碼片段、代碼對比 Diff、GIT 等特性,支持插件擴展,并針對網(wǎng)頁開發(fā)和云端應(yīng)用開發(fā)做了優(yōu)化。軟件跨平臺支持 Win、Mac 以及 Linux。

這是一個通用的代碼編輯器,裝完之后要再裝一下go的擴展:

  1. 點開,菜單-查看>>擴展
  2. 搜索“go”,找到“Rich Go language support for Visual Studio Code”,作者“l(fā)ukehoban”,安裝
  3. 裝好之后用的時候

調(diào)試工具

Delve是一個非常棒的golang調(diào)試工具,支持多種調(diào)試方式,直接運行調(diào)試,或者attach到一個正在運行中的golang程序,進行調(diào)試。
安裝Delve非常簡單,直接運行 go get 即可:

go get -u github.com/derekparker/delve/cmd/dlv

先記一下,我并沒有裝

寫代碼

在第一次寫代碼前,還要先把go的工作區(qū)設(shè)置好。

設(shè)置工作區(qū)

工作區(qū)是存放go源碼文件的目錄。一般情況,Go源碼文件都需要存放到工作區(qū)中,不過命令源碼文檔不是必須的。
每個工作區(qū)的目錄結(jié)構(gòu)都類似,有3個文件夾:

  • src/: 用于存放源碼以代碼包為組織形式
  • pkg/: 用于存放歸檔文件(名稱以.a為后綴的文件)
  • bin/: 用于存放當前工作區(qū)中的GO程序的可執(zhí)行文件

找一個合適的位置,作為工作區(qū)。比如:E:\Go。這時就可以去把GOPATH環(huán)境變量設(shè)置為 “E:\Go” 。
按上面說的,還要工作區(qū)中還要創(chuàng)建3個文件夾,暫時只需要src,另外兩個暫時不用。

Hello World

到這里需要一些儀式感,就是寫一個 Hellow World 。在src目錄下創(chuàng)建文件 “hellow.go” 。如果用了VS Code,會提示你裝一些擴展,點下Install All,這樣會自動把一些go的插件給裝好。
下面是程序的源碼:

package main

import(
    "fmt"
)

func main() {
    fmt.Println("Hello World")
}

第一部分,聲明這是一個包??蓤?zhí)行文件的包名必須是“main”。
第二部分,導(dǎo)入包。所有的庫,包括自己的庫,用之前都需要導(dǎo)入。fmt是包名,里面有一個方法可以向終端打印信息。
第三部分,定義了一個函數(shù)。必須要定義一個main函數(shù),這是個入口函數(shù)。
最后在cmd命令行里運行一下:

go run hello.go

做加法

這次寫一個有參數(shù)有返回值的函數(shù):

package main

import(
    "fmt"
)

func add(a int, b int) int {
    var sum int
    sum = a + b
    return sum
}

func main(){
    var c int
    c = add(11, 22)
    fmt.Println("11 + 22 =", c)
}

go是一個強類型語言,所有變量都要設(shè)置類型。
add函數(shù),寫參數(shù)的時候,參數(shù)后面要用類型。并且由于add函數(shù)有返回值,返回值的類型也要在函數(shù)名后面定義好。
聲明變量用var,后面是變量名,在后面是變量的類型。
最后如果你的變量定義之后,沒有被應(yīng)用,也是會報錯的。這樣強制你去掉冗余的代碼,這個變量既然沒有用到,自然就不需要出現(xiàn),比如把最后一句fmt.Println(c)去掉或者換成打印一個固定的字符串就會報錯。

golang語言特性

  1. 垃圾回收
    • 內(nèi)存自動回收,不需要開發(fā)人員管理內(nèi)存
    • 開發(fā)人員專注業(yè)務(wù)實現(xiàn),減輕負擔
    • 只需要new分配內(nèi)存,不需要釋放
  2. 天然并發(fā)
    • 從語言層面支持并發(fā),非常簡單
    • goroute,輕量級線程,創(chuàng)建成千上萬個goroute成為可能
    • 基于CSP(Communicating Sequential Process)模型實現(xiàn)
  3. channel
    • 管道,類似Linux中的pipe
    • 多個goroute之間通過channel進行通信
    • 支持任何類型
  4. 多返回值
    • 一個函數(shù)返回多個值

并發(fā)代碼演示

先寫一個程序goroute_print.go,很簡單,就是傳入?yún)?shù)稍微計算一下,然后打印結(jié)果:

package main

import (
    "fmt"
)

func goroute_print(a int) {
    b := a + 10000
    fmt.Println(b)
}

這里用了 “:=” ,是聲明并賦值,并且系統(tǒng)自動推斷類型,不需要var關(guān)鍵字。
然后再寫一個程序goroute_for.go,里面是一個for循環(huán),起若干個線程執(zhí)行:

package main

import(
    "time"
)

func main(){
    for i := 0; i < 1000; i++ {
        go goroute_print(i)
    }

    // sleep1秒,保證上面的子線程運行結(jié)束
    time.Sleep(time.Second * 5)
}

在這個主程序要里調(diào)用另外一個文件里的程序。不過這2個文件都是同一個包,main包,開頭package聲明的。這里在前面加上了go調(diào)用,就是起了一個goroute。(不加go調(diào)用,就是在主線程里調(diào)用函數(shù),如果調(diào)用前加上go,就是起了一個子線程調(diào)用這個函數(shù))
主線程必須要等待子線程運行結(jié)束才能退出,否則主線程一旦結(jié)束,其他子線程也就沒有了。這里簡單粗暴的先用sleep來進行等待。導(dǎo)入了一個time包。參數(shù) time.Second 就是1秒,如果不是等1秒而是幾秒的話,就乘以幾。
這里還有注釋,注釋的用法js一樣。單行注釋以 // 開頭,多行注釋以 /* 開始,以 */ 結(jié)尾。

執(zhí)行的話在cmd命令行執(zhí)行下面的命令:

go run goroute_for.go goroute_print.go

這個例子分在兩個文件里了,所以run后面把兩個文件都要寫上。順序是無所謂的。

管道代碼示例

這里用了make()函數(shù),是用來分配內(nèi)存的。第一個參數(shù) chan int ,表示要創(chuàng)建的是chan(管道),類型是int:

package main

import(
    "fmt"
)

func main(){
    pipe := make(chan int, 3)  // 創(chuàng)建一個管道,存的數(shù)據(jù)類型是int,容量是3
    pipe <- 11  // 往管道里存一個數(shù)
    fmt.Println(11, len(pipe))  // 打印長度
    pipe <- 22
    fmt.Println(22, len(pipe))

    var t1 int
    t1 =<- pipe  // 從管道里取出一個數(shù),賦值給t1
    fmt.Println(t1, len(pipe))
    t1 =<- pipe
    fmt.Println(t1, len(pipe))
}

似乎就是個隊列,先進先出,默認滿了也會阻塞。之所以叫管道不叫隊列,可能是它能支持多個goroute之間通過channel(管道)進行通信。暫時不需要這么深入。

通過管道在goroute之間傳遞參數(shù)

有兩種方式可以實現(xiàn)。把管道定義為全局變量,或者把管道作為函數(shù)的參數(shù)傳遞。代碼中使用全局變量不是好的做法,所以推薦用傳參的方法。不過兩種實現(xiàn)方法都看一下。
全局變量的代碼示例:

package main

import(
    "fmt"
)

var pipe chan int  // 在全局聲明pipe變量,下面兩個方法里都會用到

func add(a int, b int){
    sum := a + b
    pipe <- sum
}

func main(){
    pipe = make(chan int, 1)
    go add(1, 2)
    sum :=<- pipe
    fmt.Println("sum =", sum)
}

傳遞參數(shù)的代碼示例:

package main

import(
    "fmt"
)

func add(a int, b int, c chan int){
    sum := a + b
    c <- sum
}

func main(){
    var pipe chan int  // 在main函數(shù)里聲明pipe
    pipe = make(chan int, 1)
    go add(3, 4, pipe)
    sum :=<- pipe
    fmt.Println("sum =", sum)
}

多返回值的代碼示例

package main

import(
    "fmt"
)

func calc(a int, b int)(int, int){
    c1 := a + b
    c2 := (a + b)/2
    return c1, c2
}

func main(){
    sum , avg := calc(100, 200)
    fmt.Println("sum =", sum, "avg =", avg)
}

如果多返回值里只想取其中部分的值,可以把剩下的值傳給占位符(“_”):

package main

import(
    "fmt"
)

func calc(a int, b int)(int, int){
    c1 := a + b
    c2 := (a + b)/2
    return c1, c2
}

func main(){
    sum , _ := calc(100, 200)
    fmt.Println("sum =", sum)
    fmt.Println(_)  // 打印下劃線會報錯
}

嘗試打印下劃線的報錯信息如下:

>go run calc.go
# command-line-arguments
.\calc.go:17:16: cannot use _ as value

代碼格式化(gofmt)

go默認提供一個代碼格式化命令 gofmt ,會按照Go語言代碼規(guī)范格式化文件中的代碼。把之前的hello.go的代碼搞亂一點,簡單一點就改下縮進好了,然后運行下面的命令:

gofmt hello.go

最終還是能再命令行里看到整潔的代碼
Go語言1
還截圖的效果,縮進是8個字符的位置。
不過原文件里還是亂糟糟的,可以加上-w參數(shù),改寫原文件:

gofmt -w hello.go

實際寫到文件里,縮進用的不是空格是Tab,具體效果是幾個字符就看文件的設(shè)置了。
另外換行是 \n ,這個windows的記事本下會用問題,記事本的換行是 \r\n

編譯Go源文件

創(chuàng)建Go工作目錄:H:\Go\src\go_dev\day1\hello\。把之前寫的示例hello.go放到hello目錄下。再建個文件夾,其他示例的源文件放到examples目錄下。這里src文件夾的名字是不能變的,其他文件夾的名字包括上級的都隨意。
上面的演示都沒有對go的原文件進行編譯,編譯要用 go build 命令:

H:\Go>go build go_dev\day1\hello
can't load package: package go_dev/day1/hello: cannot find package "go_dev/day1/hello" in any of:
        D:\Go\src\go_dev\day1\hello (from $GOROOT)
        C:\Users\Steed\go\src\go_dev\day1\hello (from $GOPATH)

H:\Go>

這里并沒有編譯成功,原因是找不到我們的源文件。之前因為沒設(shè)置環(huán)境變量GOPATH,所以默認沒有設(shè)置GOPATH就是把用戶家目錄作為GOPATH。這個GOPATH就是工作目錄。
先去把GOPATH的環(huán)境變量設(shè)置好,我這里 “H:\Go\“ 就是我的工作目錄,設(shè)置成:“H:\Go\“ 。建議設(shè)置用戶變量,當然系統(tǒng)變量也沒問題。
完成之后要新開一個cmd,也有可能有要注銷當前用戶,下次登錄才能完全生效。然后可以驗證一下:

C:\Users\Steed>go env GOPATH
H:\Go\

然后再編譯一下,這次隨便找個目錄執(zhí)行命令:

J:\tmp>go build go_dev\day1\hello

J:\tmp>hello.exe
Hello World

命令執(zhí)行后會在當前目錄下生成hello.exe的可執(zhí)行文件,上面也直接執(zhí)行了一下。文件名以及生成文件的路徑都是可以用參數(shù)指定的。
前面只所以不把所有的示例都放一起,是因為其他示例也有main入口函數(shù),存在多個入口函數(shù)編譯會報錯。
其實可以編譯單個文件,但是路徑要寫全(絕對路徑或相對路徑),單文件編譯似乎不受環(huán)境變量影響:

J:\tmp>go build H:\Go\src\go_dev\day1\hello\hello.go

復(fù)雜一點的程序一般都不是單個文件的,所以一個文件夾里就是一個小項目,只有一個入口函數(shù)。這樣編譯不會有問題。另外如果使用開發(fā)工具的話,這種情況開發(fā)工具直接也會提示錯誤的。
最后,下面這么搞比較方便:

H:\Go\src>go build go_dev\day1\hello

H:\Go\src>go build go_dev\day1\hello\hello.go

選好cmd的啟動路徑,之后源文件的路徑用Tab就能自動補全出來了。

包的概念

代碼不能單獨存在,任何代碼都屬于一個包。所以第一行代碼,一定寫的是package。

  1. 把相同功能的代碼放到一個目錄,稱之為包。
  2. 包可以被其他包調(diào)用。
  3. main包是用來生成可執(zhí)行文件的,沒個程序只有一個main包
  4. 包的主要用途是提高代碼的可復(fù)用性。

使用多個包的代碼示例

新建個文件夾package_exampl,寫一個由多個包多個文件構(gòu)成的代碼,具體如下:

// go_dev/day1/package_example/calc/add.go
package calc

func Add(x int, y int) int {
    return x + y
}

// go_dev/day1/package_example/calc/sub.go
package calc

func Sub(x int, y int) int {
    return x - y
}

// go_dev/day1/package_example/main/main.go
package main

import(
    // "calc"
    "go_dev/day1/package_example/calc"
    "fmt"
)

func main(){
    sum := calc.Add(100, 200)
    sub := calc.Sub(10, 5)
    fmt.Println(sum, sub)
}

calc包里的Add和Sub函數(shù)都是首字母大寫的。在Go語言里首字母大寫有特殊的意義,就是全局變量。如果都小寫的話,在main函數(shù)里這兩個函數(shù),由于作用域的問題,都是不可見的。
結(jié)論:就是說一個變量(包括函數(shù)),如果要被外部的包調(diào)用,必須要首字母大寫。不過變量不推薦這么做,因為這樣這個變量就是全局變量,而全局變量是不推薦使用的方法(別的語言里也同樣是不推薦使用全局變量的)。
main函數(shù)里導(dǎo)入包的時候,calc包的路徑要寫全,不能只寫 “calc” ,下面會具體分析。
編譯過程
先把import改成這樣,一步一步排錯:

import(
    "calc"
    // "go_dev/day1/package_example/calc"
    "fmt"
)

多個包的編譯

H:\Go\src>go build go_dev\day1\package_example
can't load package: package go_dev/day1/package_example: no Go files in H:\Go\src\go_dev\day1\package_example

這里報錯,因為文件夾下確實沒有包,包的源文件在下一級的目錄里:

H:\Go\src>go build go_dev\day1\package_example\main
go_dev\day1\package_example\main\main.go:4:5: cannot find package "calc" in any of:
        D:\Go\src\calc (from $GOROOT)
        H:\Go\src\calc (from $GOPATH)

繼續(xù)報錯,這是找不到calc包,并且這里也看到了默認查找包的路徑?,F(xiàn)在包的路徑應(yīng)該怎么寫全就清除了,把import的內(nèi)容改回來,之后就能順利的編譯執(zhí)行了:

H:\Go\src>go build go_dev\day1\package_example\main

H:\Go\src>main.exe
300 5

指定路徑和文件名
一般編譯后生成的可執(zhí)行文件是放在工作目錄下的bin目錄下的。還是用go build命令,加上-o參數(shù),windows系統(tǒng)下得加上擴展名exe之后才能執(zhí)行:

H:\Go\src>go build -o ../bin/test.exe go_dev\day1\package_example\main

H:\Go\src>cd ../bin

H:\Go\bin>test
300 5

H:\Go\bin>

線程和管道的代碼示例

程序分成2部分。一部分是業(yè)務(wù)邏輯,放在goroute目錄下。還有一部分是函數(shù)的入口,放在main目錄下。文件結(jié)構(gòu):

H:\GO\SRC\GO_DEV\DAY1\GOROUTE_EXAMPLE
├─goroute
└─main

業(yè)務(wù)邏輯就是,獲取3個變量,2個數(shù)和1個管道,把2個數(shù)的和計算后,存到管道里。
主函數(shù)里則是,單獨起一個線程goroute進行計算,之后從管道里獲取到計算結(jié)果,打印出來。
這個例子里用到了線程goroute,以及管道用于goroute之間的通信。之前已經(jīng)演示過了,這里就是把代碼分成2個包再寫一遍:

// goroute/add.go
package goroute

func Add(a int, b int, c chan int){
    sum := a + b
    c <- sum
}

// goroute/main.go
package main

import(
    "go_dev/day1/goroute_example/goroute"
    "fmt"
)

func main(){
    var pipe chan int
    pipe = make(chan int, 1)

    go goroute.Add(100, 200, pipe)
    res := <- pipe
    fmt.Println(res)    
}

官網(wǎng) Go 指南

都是中文版的。
Go 語言之旅:https://tour.go-zh.org/welcome/1
Go 編程語言:https://go-zh.org/
Go 語言之旅可以作為入門教程,并且可以Web在線寫代碼,提交執(zhí)行在Web上顯示結(jié)果。

課后作業(yè)

使用fmt分別打印字符串、二進制、十進制、十六進制、浮點數(shù)。


網(wǎng)站名稱:Go語言1
文章URL:http://weahome.cn/article/pihjgo.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部