1.常用命令
- go get 獲取遠程包
- go run 直接運行程序
- go build 測試編譯,檢查是否有編譯錯誤
- go fmt 格式化源碼(部分IDE在保存時自動調用)
- go install 編譯包文件並編譯整個程序
- go test 運行測試文件
- go doc 查看文檔
2.第一個go程序
package main
import (
"fmt"
)
func main() {
fmt.Println("hello 世界!")
}
控制檯輸出:
➜ go run test.go
hello 世界!
3.基礎知識點
- Go程序是通過package來組織的
- 只有package名稱爲main的包可以包含main函數
- 一個可執行程序有且僅有一個main包
- 通過import關鍵字來導入其他非main包
package main //當前程序的包名,必須寫在第一行
import "fmt" //import關鍵字導入其他的包
import abc "fmt" //包別名,用abc替換fmt
import(
"fmt" //多個包用()
"time"
)
const PI = 3.14 //常量的定義
var name = "yuanmie" //全局變量的聲明與賦值
type newType int //一般類型聲明
type gopher struct{} //結構的聲明
type golang interface{} //接口的聲明
func main() { //由main函數作爲程序入口點啓動
fmt.Println("hello 世界!")
}
導入包之後,就可以使用 <包名>.<函數名>來對包中的函數進行調用,例如:
func main() {
fmt.Println("hello 世界!")//fmt是包名,Println是函數名
}
如果導入包之後未調用其中的函數或者類型將會報出編譯錯誤
package main
import (
"fmt"
"time" //導入了time包,但是沒調用就會報錯
)
func main() {
fmt.Println("hello 世界!")
}
控制檯:
➜ gogogo go run test.go
# command-line-arguments
./test.go:9: imported and not used: "time"
4.可見性規則
Go語言中,使用大小寫來決定該常量,變量,類型,接口,結構或函數是否可以被外部包所調用,根據規定:
- 函數名首字母小寫,即爲private私有的,不可被外部調用
- 函數名首字母大寫,即爲public共有的,可以被外部調用
5.基本類型
- 布爾型:bool 長度:1字節
取值範圍:true, false
注意事項:不可以用數字代表true或false - 整型:int/uint
根據運行平臺可能爲32或64位 - 8位整型:int8/uint8
長度:1字節
取值範圍:-128 ~ 127 / 0~255 - 16位整型:int16/uint16
長度:2字節
取值範圍:-32768 ~ 32767 / 0~65535 - 32位整型:int32(rune別名)/uint32
長度:4字節
取值範圍:-2^32/2 ~ 2^32/2-1 / 0 ~ 2^32-1 - 64位整型:int64/uint64
長度:8字節
取值範圍:-2^64/2 ~ 2^64/2-1 / 0 ~ 2^64-1 - 字節型:byte(uint8別名)
- 浮點型:float32/float64
長度:4/8字節
小數位:精確到7/15小數位 - 複數:complex64/complex128
長度:8/16字節 - 足夠保存指針的 32 位或 64 位整數型:uintptr
- 其它值類型:array、struct、string(數組,結構,字符串)
- 引用類型:slice、map、chan(切片,類似於哈希表,通道:用於併發)
- 接口類型:inteface
- 函數類型:func
類型零值 :
零值並不等於空值,而是當變量被聲明爲某種類型後的默認值, 通常情況下值類型的默認值爲0,bool爲false,string爲空字符串
func main() {
var a int
var b bool
fmt.Println(math.MaxInt8) //127
fmt.Println(a) //0
fmt.Println(b) //false
}
類型別名
type (
byte int8
rune int32
xxx string //xxx替代string
)
func main() {
var a xxx; //變量a就是字符串類型
a = "hahaha"
fmt.Println(a)//0
}
6.變量
單個變量的聲明與賦值
var a int; //變量的聲明
a = 1; //變量的賦值
var b int = 123; //聲明同時賦值
var c = 234; //省略變量類型,由系統推斷
d := 456//簡寫,全局聲明變量不可以簡寫,只有方法內聲明纔可以簡寫
多個變量的聲明與賦值
- 全局變量的聲明可使用 var() 的方式進行簡寫
- 全局變量的聲明不可以省略 var,但可使用並行方式
- 所有變量都可以使用類型推斷
- 局部變量不可以使用 var() 的方式簡寫,只能使用並行方式
// var (
// a = 1
// b = 2
// c = 3
// d = 4
// )
func main() {
//var a, b, c, d = 1,2,3,4
a, b, c, d := 1,2,3,4
fmt.Println(a) //1
fmt.Println(b) //2
fmt.Println(c) //3
fmt.Println(d) //4
}
變量的類型轉換
- Go中不存在隱式轉換,所有類型轉換必須顯式聲明
- 轉換隻能發生在兩種相互兼容的類型之間
package main
import (
"fmt"
"strconv"
)
func main() {
var a float32 = 100.111;
fmt.Println(a); //100.111
b := int(a);
fmt.Println(b); //100
var c bool = true;
d := int(c)//轉換不了,無法通過編譯
var a int = 65;
b := string(a);
c := strconv.Itoa(a);
fmt.Println(a) //64
fmt.Println(b) //A
fmt.Println(c) //65
//string() 表示將數據轉換成文本格式,因爲計算機中存儲的任何東西
//本質上都是數字,因此此函數自然地認爲我們需要的是用數字65表示
//的文本 A。
//引入strconv包,調用strconv包裏的Itoa方法就會打印出65,而不是轉成A
}
7.常量
常量的定義
- 常量的值在編譯時就已經確定
- 常量的定義格式與變量基本相同
- 等號右側必須是常量或者常量表達式
- 常量表達式中的函數必須是內置函數
- 常量規範最好大寫
常量的初始化規則與枚舉
- 在定義常量組時,如果不提供初始值,則表示將使用上行的表達式
const(
a = 1;
b
)
func main() {
fmt.Println(a) //1
fmt.Println(b) //1
}
- 使用相同的表達式不代表具有相同的值
- iota是常量的計數器,從0開始,組中每定義1個常量自動遞增1
- 通過初始化規則與iota可以達到枚舉的效果
- 每遇到一個const關鍵字,iota就會重置爲0
const(
a = 'A'
b = iota
c = 'B'
d = iota
)
const(
e = iota
)
func main() {
fmt.Println(a) //65
fmt.Println(b) //1
fmt.Println(c) //66
fmt.Println(d) //3
fmt.Println(e) //0
}
8.運算符
Go中的運算符均是從左至右結合
func main() {
fmt.Println(1 << 10) //左移 1024
}
/*
6 : 0110
11: 1011
--------------------
& 0010 都爲1,才爲1 2
| 1111 有一個1,就爲1 15
^ 1101 只有一個1時候才爲1 13
&^ 0100 第二個數爲1時,第一個相對應的數強制變爲0 4
*/
func main() {
fmt.Println(6 & 11) //2
fmt.Println(6 | 11) //15
fmt.Println(6 ^ 11) //13
fmt.Println(6 &^ 11) //4
}
demo
結合常量的iota與<<運算符實現計算機儲存單位的枚舉
const(
B float64 = 1 << (iota * 10)
KB
MB
GB
)
func main() {
fmt.Println(B) //1
fmt.Println(KB) //1024
fmt.Println(MB) //1.048576e+06
fmt.Println(GB) //1.073741824e+09
}
9.指針
Go雖然保留了指針,但與其它編程語言不同的是,在Go當中不支持指針運算以及”->”運算符,而直接採用”.”選擇符來操作指針目標對象的成員
- 符”&”取變量地址,使用”*”通過指針間接訪問目標對象
- 默認值爲 nil 而非 NULL
func main() {
a := 1
var p *int = &a
fmt.Println(p) //0xc42000e218 指向的是p的內存地址
fmt.Println(*p) //1
}