前言:
博主在開發C/C++程序過程中,遇到的許多語法繁瑣困擾,在學習GOLANG時。都予以解答。GOLANG的語法特性讓我驚喜。
本文會忽略一些語法通識,如果你有C或者C++語言基礎,你可以閱讀博主的學習筆記讓你快速對golang的語法有認知。如果你是新手,建議閱讀《go聖經》來完成你的入門。
代碼格式化
golang提供代碼風格格式化工具gofmt,運行命令【gofmt -w 目標文件】,會對目標文件代碼風格做自動格式化操作。一般IDE工具在保存源碼時,會自動對代碼風格做格式化。
命令行參數
golang提供“os”package用於獲取程序輸入參數,有點像C中的main(int agrc, char agrv)。通過os.Args這個string slice變量來獲取入參,
os.Args[0]爲命令本身,os.Args[1:]爲命令行參數。
package main
import (
"fmt"
"os"
)
func main() {
fmt.Println(os.Args[1:])
}
變量
golang變量關鍵字爲var,定義變量時需聲明其變量類型,變量聲明時如果未賦值,則自動賦值爲二進制零。常見的變量定義方式有:
var a int // a變量自動初始化爲0,類型爲int
var b = false // y變量自動判斷類型爲bool,值爲false
var c, d string // 同時定義相同類型的多個變量,c,d都爲string類型
var e, f = 12, "hello" // 同時定義不同類型的多個變量,e爲int型,f爲string類型
var ( // 以組的方式進行定義
g, h int
i, j = 1.1, "world"
)
k := 13.1 // 簡短模式定義變量,忽略var關鍵字
l, m := 14.1, "no var" // 簡短模式定義變量,忽略var關鍵字
簡短模式定義變量需要注意三個點:1)定義變量,同時顯示初始化 2)不能提供數據類型 3)只能用在函數內部,不能作爲全局變量的定義方式。
package main
import "fmt"
var a = 1
func main() {
fmt.Println(&a, a) // 打印全局變量a的地址和值
a := 2 // 定義了一個局部變量a,並賦值爲2
fmt.Println(&a, a) // 由於局部變量優先級高於全局變量,這裏打印的是局部變量a的地址和值
}
當然,也並不是每次調用簡短模式都會重新定義一個局部變量,假設在同一個作用域,之前已經定義過該變量,且使用簡短模式【:=】時,左邊有新定義的變量,則簡短模式只會對已定義的變量值進行重新賦值操作。
package main
import (
"fmt"
"os"
)
func main() {
a, err := os.Open("var.go") //簡短模式定義了err變量
fmt.Println(a, err, &err)
buf := make([]byte, 1024)
n, err := a.Read(buf) // 由於n爲新定義的變量,err變量在局部變量中已定義,則對err進行重新賦值
fmt.Println(n, err, &err)
}
常量
golang常亮關鍵字爲const,常量在定義時需明確其類型和數值,在定義後不允許修改。需要注意的是,常量在程序編譯器預處理階段,
直接展開作爲指令數據使用,常量不被分配內存空間,因此常量無法通過&來獲取其地址,常見的常量定義方式:
package main
import "fmt"
func main() {
const a = 3.14
const b, c int = 1, 2
const (
d bool = true
e // 以組定義時,e類型和值和上一行d一致
f int = 4
g // 以組定義時,g類型和值和上一行f一致
)
fmt.Println(a, b, c, d, e, f, g)
}
枚舉
golang通過關鍵字iota來實現枚舉遞增,常見的使用方式:
package main
import "fmt"
func main() {
const (
a = iota // iota默認爲int型,值爲0
b // int型,值爲1
c = 100 // 中斷遞增 100
d // 100
)
const (
_, _ = iota, iota * 10 // 0, 0*10 int
e, f //1, 1*10 int
g, h //2, 2*10 int
)
const (
_ float32 = iota
i // float型 值爲1
)
fmt.Println(a, b, c, d, e, f, g, h, i)
}
空標識符
golang中空標識符【_】用做忽略佔位符使用,可作表達式作值,無法讀取其內容。空標識符爲預置變量,不可重新定義。
func test(a int) (int, int) {
return 0, a + 1
}
func main() {
_, a := test(1)
fmt.Println(a)
}
數據類型
golang有26種基礎數據類型,跨平臺使用無需過多考慮其長度差異
類型 |
長度 (字節) |
默認值 | 說明 |
---|---|---|---|
bool | 1 | fasle | |
byte | 1 | 0 | uint8相同 |
int,uint | 4,8 | 0 | 整數類型,依據平臺,可能32或者64位 |
int8,uint8 | 1 | 0 | -128~127,0~255 |
int16,uint16 | 2 | 0 | -32768~32767,0~65535 |
int32,uint32 | 4 | 0 |
-4 294 967 296~4 294 967 295, 0~8 589 934 592 |
float32 | 4 | 0.0 | |
float64 | 8 | 0.0 | 默認浮點數類型 |
complex64 | 8 | 複數,實部和虛部都爲float | |
complex128 | 16 | 複數,實部和虛部都爲float | |
rune | 4 | 0 | int32別名,常用於處理中文字符 |
uintprt | 4,8 | 0 | 足以存儲指針的unit |
string | "" | 字符串,默認值爲空字符串,而非NULL | |
array | 數組 | ||
struct | 結構體 | ||
function | nil | 函數 | |
interface | nil | 接口 | |
map | nil | 字典,引用類型 | |
slice | nil | 切片,引用類型 | |
channel | nil | 通道,引用類型 |
rune
rune常在開源代碼中遇見,用於處理中文字符。golang默認編碼爲utf8,中文字符佔3個字節。而字符默認類型爲byte(1個字節)。
在計算時,使用rune類型可以獲取字符串長度,而不是佔用字節長度。
package main
import "fmt"
func main() {
var buf = "123木頭人"
fmt.Println(len(buf))
fmt.Println(len([]rune(buf)))
}