Go編程語言:支持併發、垃圾回收的編譯型系統級編程語言!本文主要是按照無聞的《Go 編程基礎》開源視頻學習並記錄筆記。git
go get 獲取遠程包(需提早安裝git) go run 運行 go build 測試編譯(package main 的文件) go fmt 格式化代碼 go install 編譯包文件和整個程序 go test 運行測試文件(**_test.go是測試文件,命名本身文件的時候須要注意) go doc 查看文檔(本地官網 godoc -http=:8080 & 後臺執行)
咱們能夠將go的官網放到本地:github
godoc -http=:8080
而後咱們能夠訪問本地8080端口:golang
Go環境變量與工做目錄:GOPATH下須要創建 3個目錄(bin存放編譯後生成的可執行文件;pkg存放編譯後生成的包文件;src存放項目源碼)數組
package main包含main函數一個程序有且只有一個main包和一個main函數
package 要放在非註釋的第一行
package 後加import,import 引入非main包
通常建議package的名稱和目錄名一致 pacage 名稱不要使用駝峯標記法,使用下劃線
var 全局變量
type 基本類型 好比:type newtype struct/interface{(內容)}併發
改包名:app
import abc "fmt"/import . "fmt"
調用的時候編程語言
abc.Println/Println
不推薦使用.那種,容易混淆函數
只有
package
爲main
的包能夠包含main函數,一個可執行程學習
test.go
package ok // package main 這裏故意將main 包名寫錯 import "fmt" func main(){ fmt.Println("Hello, World") }
若是咱們運行的程序裏邊沒有 package main
包,則執行會報錯;➜ src go run myfirstgo/test.go go run: cannot run non-main package
未調用
其中的函數
或類型
將會報出編譯錯誤import and not used:"io";
當使用第三方包時,包名可能會很是接近或相同,此時就可使用別名來進行區別和調用
import "fmt" // 使用別名 import std "fmt" std.Println("Hello,world")
省略調用
// 省略調用 import . "fmt" Println("Hello,world")
注意點:
1.不建議使用
省略調用,易混淆
2.不能夠
和別名同時使用
Go語言中,使用 大小寫
來決定該常亮、變量、類型、接口、結構或函數,是否能夠被外部包所調用:
根據約定,函數名
首字母小寫
即爲private
func getField(){ // ... }
函數名
首字母大寫
即爲public
func Print(){ // ... }
完整示例:
package main // 導入其餘的包 import "fmt" // 第一種導入方法 /* import{ "fmt" "io" "os" } */ // 常量的定義 const PI = 3.14 // 全局變量的聲明與賦值 var name = "gopher" // 通常類型聲明 type newType int // 結構的聲明 type gopher struct{} // 接口的聲明 type golang interface{} // 由 main 函數做爲程序入口點啓動 func main(){ fmt.Println("Hello, World") }
牛刀小試:
既然導入多個包能夠進行簡寫,那麼聲明多個常亮、全局變量或通常類型(非接口、非結構)是否也可使用一樣的方法呢?
定義常亮:
const( PI = 3.14 const1 = 1 Radis = 10 )
全局變量的聲明與賦值:
var ( name = "corwien" age = 20 address = "guangzhou" )
通常類型聲明:
type ( newType int type1 float32 )
一、布爾類型:bool
長度:1字節
取值範圍:true,false
注意事項:不能夠用數字表明true或false
二、整型:int/uint
-根據運行平臺可能爲32或64位
三、8位整型:int8/uint8
-長度:1字節
-取值範圍:-128~127/0~255
四、字節型:byte(uint8別名
)
五、16位整型:int16/uint16
-長度:2字節
-取值範圍:-32768~32767/0~65565
六、32位整型:int32(rune)/uint32
-長度:4字節
-取值範圍:-32768~32767/0~65565
七、浮點型:float32/float64
-長度:4/8字節
-小數位:精確到7/15小數位
八、複數:complex64/complex128
-長度:8/16字節
足夠保存指針的3二、64位整數型:uintptr
九、其餘值類型:
十、引用類型:
十一、接口類型:interface
十二、函數類型:func,能夠賦值給變量
類型零值
零值並不等於空值,而是當變量被聲明爲某種類型後的默認值,一般狀況下值類型的默認值爲0,bool爲false, string爲空字符串
類型別名
type ( byte int8 rune int32 文本 string ) // 使用中文類型,牛逼啊 var b 文本 b = "你好哈親"
var <變量名稱><變量類型>
<變量名稱> = <表達式>
var <變量名稱>[變量類型] = <表達式>
示例:
var a int // 變量的聲明 a = 123 // 變量的賦值 // 變量聲明的同時賦值 var a int = 123 // 上行的格式可省略變量類型,由系統推斷 var c = 123 // 變量聲明與賦值的最簡寫法 d := 678
d := 678 冒號的做用就是代替關鍵字 var 的
var()
的方式進行簡寫並行
方式全部變量均可以使用類型推斷
局部變量不可使用var()的簡寫,只能使用並行方式
舉例:
var( // 使用常規方式 a = 'hello' // 使用並行方式以及類型推斷 b,c = 1,2 // d := 3 // 不能夠省略 var )
多個變量的聲明
// 多個變量的聲明 var a, b, c int // 多個變量的賦值 a, b, c = 1, 2, 3 // 多個變量聲明的同時賦值 var d, e, f int = 4, 5, 6 // 省略變量類型,有系統推斷 var g, h, m = 7, 8, 9 // 多個變量聲明與賦值的最簡寫法 n, o, p := 10, 11, 12
Go中不存在隱式轉換,全部類型轉換必須顯示聲明
只能發生在兩種相互兼容的類型
之間// 當變量未在前邊申明過,則須要冒號:,若是已經聲明過,則不須要冒號 <ValueA>[:] = <TypeOfValueA>(<ValueB>)
示例:
// 在相互兼容的兩種類型之間轉換 var a float32 = 1.1 b := int(a) // 如下表達式沒法經過編譯 var c bool = true d := int(c)
全局變量的聲明不能夠省略var 局部變量不可使用var()的方式簡寫
思考
嘗試運行下邊的代碼,開會發生什麼,並思考爲何?
// 變量類型轉換,整數轉爲字符,會發生什麼呢? func main() { var a int = 65 b := string(a) fmt.Println(b) }
// 定義單個常量 const a int = 1 const b = 'A' const { text = "123" length = len(text) num = b * 20 } // 同時定義多個變量 const i, j, k = 1, "2", "3" const( text2, length2, num2 = "234", len(text2), k * 10 )
iota
是常量的計數器,從0開始,組中每定義1個常量自動遞增1iota
能夠達到枚舉的效果示例:
const ( // a與b都爲"A" a = "A" b c = iota d // d的值爲3 ) const( e = iota f // f 的值爲1 ) // 星期枚舉 const( // 第一個常量不可省略表達式 Monday = iota Tuesday Wednesday Thursday Firday Saturday Sunday )
Go雖然保留了指針,但與其餘編程語言不一樣的是,在Go當中不支持指針運算以及「->」運算符,而直接採用「.」選擇符來操做指針目標對象的成員
間接
訪問目標對象nil
而非NULLfunc main() { a := 1 var p *int = &a; // fmt.Println(p) 打印地址:0xc42000e228 fmt.Println(*p) // 打印結果: 1 }
在Go當中, ++ 與 -- 是做爲語句而並非做爲表達式
條件表達式沒有括號
,這和其餘語言不太同樣左大括號必須和條件語句或else在同一行
示例:
package main import "fmt" func main() { a := true // 初始化變量,在塊裏邊初始化,做用域只是在該區塊中 if a, b, c := 1, 2, 3; a+b+c > 6 { fmt.Println("大於6") fmt.Println(a) } else { fmt.Println("小於等於6") fmt.Println(a) } fmt.Println(a) }
打印結果:
➜ myfirstgo go run if.go 小於等於6 1 true
for
一個循環語句關鍵字,但支持3種形式左大括號必須和條件語句在同一行
for 循環的三種形式:
1.最簡單的
func main() { a := 1 for { a++ if a > 3 { break } } fmt.Println(a) }
二、條件語句判斷
func main() { a := 1 for a <= 3 { a++ } fmt.Println(a) }
三、最經常使用的一種方式
func main() { a := 1 for i := 0; i < 3; i++ { a++ } fmt.Println(a) }
任何類型
或表達式
做爲條件語句不須要寫break,一旦條件符合自動終止
fallthrough
語句示例:
// switch func main() { a := 1 switch a { case 0: fmt.Println("a=0") case 1: fmt.Println("a=1") default: fmt.Println("Nothing") } fmt.Println(a) }
func main() { a := 1 switch { case a >= 0: fmt.Println("a=0") fallthrough case a >= 1: fmt.Println("a=1") } fmt.Println(a) }
func main() { switch a := 1; { case a >= 0: fmt.Println("a=0") fallthrough case a >= 1: fmt.Println("a=1") } }
標籤
使用標籤名區分大小寫,若不使用會形成編譯錯誤
示例:
func main() { // 標籤 LABLE: for { for i := 0; i < 10; i++ { if i > 3 { break LABLE } } } fmt.Println("ok") }
func main() { LABLE: for i := 0; i < 10; i++ { for { continue LABLE fmt.Println(i) } } fmt.Println("ok") }
Go 語言中 range
關鍵字用於for循環中迭代數組(array)、切片(slice)、通道(channel)或集合(map)的元素。在數組和切片中它返回元素的索引值,在集合中返回 key-value 對的 key 值。
示例:
package main import "fmt" func main() { //這是咱們使用range去求一個slice的和。使用數組跟這個很相似 nums := []int{2, 3, 4} sum := 0 for _, num := range nums { sum += num } fmt.Println("sum:", sum) //在數組上使用range將傳入index和值兩個變量。上面那個例子咱們不須要使用該元素的序號,因此咱們使用空白符"_"省略了。有時侯咱們確實須要知道它的索引。 for i, num := range nums { if num == 3 { fmt.Println("index:", i) } } //range也能夠用在map的鍵值對上。 kvs := map[string]string{"a": "apple", "b": "banana"} for k, v := range kvs { fmt.Printf("%s -> %s\n", k, v) } //range也能夠用來枚舉Unicode字符串。第一個參數是字符的索引,第二個是字符(Unicode的值)自己。 for i, c := range "go" { fmt.Println(i, c) } }
運行結果:
sum: 9 index: 1 a -> apple b -> banana 0 103 1 111