Go从入门到精通(一)go语言初识
?一、第一個go程序
package mainimport ("fmt" )func main(){fmt.Println("hello world") }對于代碼的解釋
如果是為了將代碼編譯成一個可執(zhí)行程序,那么package必須是main
如果是為了將代碼編譯成庫,那么package則沒有限制
go中所有的代碼都應(yīng)該隸屬一個包
fmt 是go的一個系統(tǒng)庫
fmt.println()則可以打印輸出
如果想要運(yùn)行程序:go run 程序名
在一個可執(zhí)行程序只有一個main函數(shù)
關(guān)于注釋
單行注釋://
多行注釋:/* */
二、go語言初識
關(guān)于定義一個變量
var 變量名 變量類型
變量名 = 值
這里需要注意:go語言中定義的變量必須被用到,否則會報錯
同時定義變量和賦值可以一步完成通過: 變量名 := 值
定義一個函數(shù)
如果我們要定義一個函數(shù),我們先看下面求和的例子:
func add(a int,b int) int {var sum intsum = a + breturn sum }這里我們需要知道,下面這種格式是被嚴(yán)格要求的沒包括第一行的大括號不能放到下一行
func 函數(shù)名(參數(shù)1 參數(shù)1類型,參數(shù)2 參數(shù)2類型) 返回值類型 {?
}
三、golang語言特性
垃圾回收
內(nèi)存自動回收,不需要開發(fā)人員管理內(nèi)存
開發(fā)人員專注業(yè)務(wù)實現(xiàn)
只需要new分配內(nèi)存,不需要釋放
天然高并發(fā)
- 從語言曾元支持并發(fā),非常簡單
- goroute,輕量級線程,創(chuàng)建成千上萬goroute成為可能
- 基于CSP模型實現(xiàn)
關(guān)于高并發(fā)的一個簡單演示:
package mainimport ("fmt""time" )func test_print(a int){fmt.Println(a) }func main(){for i:= 0;i < 100; i ++ {go test_print(i)}time.Sleep(time.Second) }在實現(xiàn)高并發(fā)的時候只需要在調(diào)用的函數(shù)前面加上go,就表示開啟了并發(fā)
如果在for循環(huán)的外面不加上time.Sleep(time.Second),就會發(fā)現(xiàn)會少打印了,這是因為當(dāng)主程序運(yùn)行完之后,并不會等待線程,所以程序直接終止
channel管道
類似linux中的pipe
多個goroute之間通過channel進(jìn)行通信
支持任何類型
上述代碼的解釋:
pipe := make(chan int,3) 這里是定義一個管道pipe,go是強(qiáng)類型語言,所以這里聲明一個管道變量pipe需要通過有三個參數(shù),chan表示是管道,int表示管道類型,3表示管道容量
通過len(pipe)可以查看管道的的長度
如果想要從管道里獲取數(shù)據(jù)
t1 :=<- pipe 這個寫法等同于
var t1 int
t1 = <- pipe
fmt.Println(t1)
管道遵循的原則是先進(jìn)先出,所以第一個獲取的值是1
小結(jié):如果想要給管道放入值:定義的管道pipe < - 要存入的內(nèi)容
如果想要從管道中獲取值:變量名 =<- 定義的管道pipe
這里強(qiáng)調(diào)一下go中package包的概念,一個包里的變量,在這個包里是都可以訪問,但是在包之外也是有權(quán)限限制是否可以訪問到,如果一個變量在一個包里是大寫的,在其他包里就可以訪問到,如果是小寫的其他包里則訪問不到。類似其他語言中的public和private
多返回值
一個函數(shù)可以返回多個值
package mainimport "fmt"func calc(a int,b int) (int,int ){sum := a + bavg := sum / 2return sum,avg }func main(){sum,avg := calc(100,200)fmt.Println(sum,avg) }關(guān)于需要傳入多個參數(shù)的時候是用括號括起來單個的情況下一般不用括號括起來,直接int,而這里是返回兩個則需要 (int,int)表示返回兩個整數(shù)類型值
如果有多個返回值,但是我只想返回一個值,是通過下劃線方式實現(xiàn),則上述代碼改為:
func main(){sum,_ := calc(100,200)fmt.Println(sum) }四、包的概念
- 和python一樣,把相同功能的代碼放到一個目錄,稱之為包
- 包可以被其他包引用
- main包是用來生成可執(zhí)行文件,每個程序只有一個main包
- 包的主要用途是提高代碼的課復(fù)用性
關(guān)于main包中的main函數(shù),go程序經(jīng)過編譯之后,運(yùn)行該程序,會將編譯好的二進(jìn)制文件加載到內(nèi)存中,會首先調(diào)用main函數(shù),所以main函數(shù)是程序的入口函數(shù),即必須有package main
關(guān)于包,是我們可以把一些常用的功能封裝到包中,這個時候包中的每個go文件的開頭則不需要package main,而是package 自定義名字 這個自定義名字是根據(jù)這個包的功能進(jìn)行命名
go源碼按package進(jìn)行組織,并且package要放到非注釋的第一行
一個程序只有一個main包,一個包中只能有一個main函數(shù),不能重復(fù)定義
main函數(shù)是程序的執(zhí)行入口
沒有被引用的變量,編譯的時候會報錯
?
go的目錄規(guī)范
這里舉一個簡單的例子:如果我們在建立一個go_project目錄,通常在這個目錄下我們會創(chuàng)建如下目錄
src 存放不同的項目代碼
bin 存放編譯后的可執(zhí)行程序
vender 存放引用的第三方庫
pgk 存放靜態(tài)庫
?
我們的go環(huán)境變量中的GOPATH一般會設(shè)置為:
(我這里是路徑是/users/zhaofan/go_project)
export GOPATH=/users/zhaofan/go_project
go的編譯
如果我們寫好了go的代碼文件,我們?nèi)绻麥y試運(yùn)行可以通過:
go run 快速執(zhí)行g(shù)o文件
go build 編譯程序,生成二進(jìn)制文件
go install 安裝可執(zhí)行文件到bin目錄下
基本命令:
go test執(zhí)行單元測試或壓力測試
go env 顯示go相關(guān)的環(huán)境變量
go fmt 格式化源代碼
我們通過下面例子理解這個編譯命令的使用:
例子一
我在/users/zhaofan/go_project/src/go_dev/day01/hello目錄下寫了一個hello程序
現(xiàn)在把這個hello程序進(jìn)行編譯
我們在go_project目錄下執(zhí)行的編譯命令,如果不指定編譯生成的文件會直接將編譯文件生成在當(dāng)前目錄即go_project目錄下
這里需要解釋的是go build 后面的路徑go build go_dev/day01/hello?
我們從目錄結(jié)構(gòu)可以看出,go_dev的上一級目錄src目錄并沒有寫,這是因為go編譯的時候,會自動去GOPATH下的src目錄里去找,所以這里是不需要寫,同時編譯的路徑的最后我們只寫到hello目錄而不是hello.go文件
例子二
我們在/users/zhaofan/go_project/src/go_dev/day01/ 目錄下建立一個goroute目錄
并在goroute目錄下建立兩個go文件,main.go和goroute.go文件
main.go文件的代碼為:
package main import ("time" )func main(){for i := 0; i < 100; i++ {go test_goroute(i)}time.Sleep(time.Second) }goroute.go文件的代碼為:
package mainimport "fmt"func test_goroute(a int){fmt.Println(a) }這樣我們編譯的時候只需要在go_project目錄下執(zhí)行:
go build go_dev/day01/goroute
這樣就會再go_project目錄下生成一個可執(zhí)行文件goroute
例子3
還是在/users/zhaofan/go_project/src/go_dev/day01/下建立一個goroute_test目錄
在goroute_test目錄下建立calc目錄和main目錄
同時在calc下建立一個sum.go文件,在main目錄下建立一個main.go文件
sum.go文件代碼如下:
package calcfunc Add(a int,b int,c chan int){sum := a + bc <- sum }這里有個地方需要注意這里我們的sum.go是作為包寫的,所以我們開頭是:package calc,即package+sum.go的所在上級目錄,并且是sum中定義的函數(shù)名首字母要大些(這個是必須的)這里其實是因為
我們定義的包都是要被外部的其他包調(diào)用,即我們這里定義的sum.go是要被其他包調(diào)用,這個時候只有首字母大寫才能被其他包調(diào)用到
main.go文件代碼如下:
package mainimport ("fmt""go_dev/day01/goroute_test/calc" )func main(){pipe := make(chan int,1)calc.Add(100,200,pipe)res :=<- pipefmt.Println(res) }這次我們編譯的時候指定編譯文件生成的目錄路徑,命令如下:
go build -o bin/goroute_test go_dev/day01/goroute_test/main
?
關(guān)于單元測試?yán)?#xff1a;
單元測試的代碼文件的名字格式必須是:*_test.go
例如我要寫關(guān)于calc.go文件的單元測試
新建一個文件命名為:calc_test.go
這里需要知道的是開頭的calc的名字并不是強(qiáng)制的,但是為了方便測試哪個代碼文件,開頭就以那個文件開頭,下面是一個例子代碼:
1 package calc 2 3 import ( 4 "testing" 5 ) 6 func TestAdd(t *testing.T){ 7 var sum int 8 sum = Add(5,6) 9 if sum != 11{ 10 t.Fatalf("add is not right,sum:%v expected:11",sum) 11 } 12 t.Logf("add is Ok") 13 }在代碼中我們定義函數(shù)時候函數(shù)的名字也需要以Test開頭
上述測試文件執(zhí)行結(jié)果:
原文地址:?http://www.cnblogs.com/zhaof/p/6962813.html
與50位技術(shù)專家面對面20年技術(shù)見證,附贈技術(shù)全景圖總結(jié)
以上是生活随笔為你收集整理的Go从入门到精通(一)go语言初识的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python爬虫从入门到放弃(三)之 U
- 下一篇: go 从入门到精通(二)基本数据类型和操