尹成學院golang學習快速筆記(1)型別
1.1 變數
Go 是靜態型別語⾔,不能在運⾏期改變變數型別。
使⽤關鍵字 var 定義變數,⾃動初始化為零值。如果提供初始化值,可省略變數型別,由
編譯器⾃動推斷。
var x int
var f float32 = 1.6
var s = "abc"
在函式內部,可⽤更簡略的 ":=" ⽅式定義變數。
func main() {
x := 123
// 注意檢查,是定義新區域性變數,還是修改全域性變數。該⽅式容易造成錯誤。
}
可⼀次定義多個變數。
var x, y, z int
var s, n = "abc", 123
var (
a int
b float32
)
func main() {
n, s := 0x1234, "Hello, World!"
println(x, s, n)
}
多變數賦值時,先計算所有相關值,然後再從左到右依次賦值。
data, i := [3]int{0, 1, 2}, 0
i, data[i] = 2, 100+l
// (i = 0) -> (i = 2), (data[0] = 100)
特殊只寫變數 "_",⽤於忽略值佔位。
func test() (int, string) {
return 1, "abc"
}
func main() {
_, s := test()
println(s)
}
編譯器會將未使⽤的區域性變數當做錯誤。
var s string
func main() {
i := 0
// 全域性變數沒問題。
// Error: i declared and not used。(可使⽤ "_ = i" 規避)
}
注意重新賦值與定義新同名變數的區別。
s := "abc"
println(&s)
s, y := "hello", 20
println(&s, y)
{
s, z := 1000, 30
println(&s, z)
// 重新賦值: 與前 s 在同⼀層次的程式碼塊中,且有新的變數被定義。
// 通常函式多返回值 err 會被重複使⽤。
// 定義新同名變數: 不在同⼀層次程式碼塊。
}
輸出:
0x2210230f30
0x2210230f30 20
0x2210230f18 30
1.2 常量
常量值必須是編譯期可確定的數字、字串、布林值。
const x, y int = 1, 2
const s = "Hello, World!"
const (
// 多常量初始化
// 型別推斷
// 常量組
a, b
c= 10, 100
bool = false
)
func main() {
const x = "xxx"
// 未使⽤區域性常量不會引發編譯錯誤。
}
不⽀持 1UL、2LL 這樣的型別字尾。
在常量組中,如不提供型別和初始化值,那麼視作與上⼀常量相同。
const (
s= "abc"
x// x = "abc"
)
常量值還可以是 len、cap、unsafe.Sizeof 等編譯期可確定結果的函式返回值。
const (
a= "abc"
b= len(a)
c= unsafe.Sizeof(b)
)
如果常量型別⾜以儲存初始化值,那麼不會引發溢位錯誤。
const (
a byte = 100
// int to byte
b int= 1e20
// float64 to int, overflows
)
列舉
關鍵字 iota 定義常量組中從 0 開始按⾏計數的⾃增列舉值。
const (
Sunday = iota // 0
Monday // 1,通常省略後續⾏表示式。
Tuesday // 2
Wednesday // 3
Thursday // 4
Friday // 5
Saturday // 6
)
const (
_
KB= iota
MB
GB
TB
int64 = 1 << (10 * iota)
// iota = 0
// iota = 1
// 與 KB 表示式相同,但 iota = 2
)
在同⼀常量組中,可以提供多個 iota,它們各⾃增⻓。
const (
A, B = iota, iota << 10
C, D
// 0, 0 << 10
// 1, 1 << 10
)
如果 iota ⾃增被打斷,須顯式恢復。
const (
A= iota// 0
B= "c" // 1
C= iota// c
D // c,與上⼀⾏相同。
E // 4,顯式恢復。注意計數包含了 C、D 兩⾏。
F// 5
)
可通過⾃定義型別來實現列舉型別限制。
type Color int const ( Black Color = iota Red Blue ) func test(c Color) {} func main() { c := Black test(c) x := 1 test(x) // Error: cannot use x (type int) as type Color in function argument test(1) // 常量會被編譯器⾃動轉換。 }
⻓度 | 預設值 | 說明 | |
bool | 1 | false |
|
byte | 1 | 0 | uint8 |
rune | 4 | 0 | Unicode Code Point, int32 |
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 | -21億 ~ 21 億, 0 ~ 42 億 |
int64, uint64 | 8 | 0 |
|
float32 | 4 | 0.0 |
|
float64 | 8 | 0.0 |
|
complex64 | 8 |
|
|
complex128 | 16 |
|
|
uintptr | 4 或 8 |
| ⾜以儲存指標的 uint32 或 uint64 整數 |
array |
|
| 值型別 |
struct |
|
| 值型別 |
string |
| "" | UTF-8 字串 |
slice |
| nil | 引⽤型別 |
map |
| nil | 引⽤型別 |
channel |
| nil | 引⽤型別 |
interface |
| nil | 接⼝ |
function |
| nil | 函式 |
1.3 基本型別
明確字型別命名,⽀持 Unicode,⽀持常⽤資料結構。
⽀持⼋進位制、⼗六進位制,以及科學記數法。標準庫 math 定義了各數字型別取值範圍。
a, b, c, d := 071, 0x1F, 1e9, math.MinInt16
空指標值 nil,⽽⾮ C/C++ NULL。
1.4 引⽤型別
引⽤型別包括 slice、map 和 channel。它們有複雜的內部結構,除了申請記憶體外,還需
要初始化相關屬性。
內建函式 new 計算型別⼤⼩,為其分配零值記憶體,返回指標。⽽ make 會被編譯器翻譯
成具體的建立函式,由其分配記憶體和初始化成員結構,返回物件⽽⾮指標。
a := []int{0, 0, 0}
a[1] = 10
b := make([]int, 3)
b[1] = 10
c := new([]int)
c[1] = 10
// 提供初始化表示式。
// makeslice
// Error: invalid operation: c[1] (index of type *[]int)
1.5 型別轉換
不⽀持隱式型別轉換,即便是從窄向寬轉換也不⾏。
var b byte = 100
// var n int = b
var n int = int(b)
// Error: cannot use b (type byte) as type int in assignment
// 顯式轉換
使⽤括號避免優先順序錯誤。
*Point(p)
(*Point)(p)
<-chan int(c)
(<-chan int)(c)
// 相當於 *(Point(p))
// 相當於 <-(chan int(c))
同樣不能將其他型別當 bool 值使⽤。
a := 100
if a {
println("true")
// Error: non-bool a (type int) used as if condition
}
1.6 字串
字串是不可變值型別,內部⽤指標指向 UTF-8 位元組陣列。
• 預設值是空字串 ""。
• ⽤索引號訪問某位元組,如 s[i]。
• 不能⽤序號獲取位元組元素指標,&s[i] ⾮法。
• 不可變型別,⽆法修改位元組陣列。
• 位元組陣列尾部不包含 NULL。
//runtime.h
struct String
{
byte*
intgo
str;
len;
};
使⽤索引號問字元 (byte)。
s := "abc"
println(s[0] == '\x61', s[1] == 'b', s[2] == 0x63)
輸出:
true true true
使⽤ "`" 定義不做轉義處理的原始字串,⽀持跨⾏。
s := `a
b\r\n\x00
c`
println(s)
輸出:
a
b\r\n\x00
c
連線跨⾏字串時,"+" 必須在上⼀⾏末尾,否則導致編譯錯誤。
s := "Hello, " +
"World!"
s2 := "Hello, "
+ "World!"
// Error: invalid operation: + untyped string
⽀持⽤兩個索引號返回⼦串。⼦串依然指向原位元組陣列,僅修改了指標和⻓度屬性。
s := "Hello, World!"
s1 := s[:5]
// Hello
s2 := s[7:]
s3 := s[1:5]
// Hello
// World!
// ello
單引號字元常量表⽰ Unicode Code Point,⽀持 \uFFFF、\U7FFFFFFF、\xFF 格式。
對應 rune 型別,UCS-4。
func main() {
fmt.Printf("%T\n", 'a')
var c1, c2 rune = '\u6211', '們'
println(c1 == '我', string(c2) == "\xe4\xbb\xac")
}
輸出:
int32
// rune 是 int32 的別名
true true
要修改字串,可先將其轉換成 []rune 或 []byte,完成後再轉換為 string。⽆論哪種轉
換,都會重新分配記憶體,並複製位元組陣列。
func main() {
s := "abcd"
bs := []byte(s)
bs[1] = 'B'
println(string(bs))
u := "電腦"
us := []rune(u)
us[1] = '話'
println(string(us))
}
輸出:
aBcd
電話
⽤ for 迴圈遍歷字串時,也有 byte 和 rune 兩種⽅式。
func main() {
s := "abc漢字"
for i := 0; i < len(s); i++ {
fmt.Printf("%c,", s[i])
}
fmt.Println()
for _, r := range s {
fmt.Printf("%c,", r)
}
// byte
// rune
}
輸出:
a,b,c,æ,±,,å,,,
a,b,c,漢,字,
1.7 指標
⽀持指標型別 *T,指標的指標 **T,以及包含包名字首的 *<package>.T。
• 預設值 nil,沒有 NULL 常量。
• 操作符 "&" 取變數地址,"*" 透過指標訪問⺫標物件。
• 不⽀持指標運算,不⽀持 "->" 運算子,直接⽤ "." 訪問⺫標成員。
func main() {
type data struct{ a int }
var d = data{1234}
var p *data
p = &d
fmt.Printf("%p, %v\n", p, p.a)
}
輸出:
0x2101ef018, 1234
不能對指標做加減法等運算。
x := 1234
p := &x
// 直接⽤指標訪問⺫標物件成員,⽆須轉換。
p++
// Error: invalid operation: p += 1 (mismatched types *int and int)
可以在 unsafe.Pointer 和任意型別指標間進⾏轉換。
func main() {
x := 0x12345678
p := unsafe.Pointer(&x)
n := (*[4]byte)(p)
for i := 0; i < len(n); i++ {
fmt.Printf("%X ", n[i])
}
// *int -> Pointer
// Pointer -> *[4]byte
}
輸出:
78 56 34 12
返回區域性變數指標是安全的,編譯器會根據需要將其分配在 GC Heap 上。
func test() *int {
x := 100
return &x
// 在堆上分配 x 記憶體。但在內聯時,也可能直接分配在⺫標棧。
}
將 Pointer 轉換成 uintptr,可變相實現指標運算。
func main() {
d := struct {
s
x
string
int
}{"abc", 100}
p := uintptr(unsafe.Pointer(&d))
p += unsafe.Offsetof(d.x)
// *struct -> Pointer -> uintptr
// uintptr + offset
p2 := unsafe.Pointer(p)
px := (*int)(p2)
*px = 200
fmt.Printf("%#v\n", d)
// uintptr -> Pointer
// Pointer -> *int
// d.x = 200
}
輸出:
struct { s string; x int }{s:"abc", x:200}
注意:GC 把 uintptr 當成普通整數物件,它⽆法阻⽌ "關聯" 物件被回收。
1.8 ⾃定義型別
可將型別分為命名和未命名兩⼤類。命名型別包括 bool、int、string 等,⽽ array、
slice、map 等和具體元素型別、⻓度等有關,屬於未命名型別。
具有相同宣告的未命名型別被視為同⼀型別。
• 具有相同基型別的指標。
• 具有相同元素型別和⻓度的 array。
• 具有相同元素型別的 slice。
• 具有相同鍵值型別的 map。
• 具有相同元素型別和傳送⽅向的 channel。
• 具有相同欄位序列 (欄位名、型別、標籤、順序) 的匿名 struct。
• 簽名相同 (引數和返回值,不包括引數名稱) 的 function。
• ⽅法集相同 (⽅法名、⽅法簽名相同,和次序⽆關) 的 interface。
var a struct { x int `a` }
var b struct { x int `ab` }
// cannot use a (type struct { x int "a" }) as type struct { x int "ab" } in assignment
b = a
可⽤ type 在全域性或函式內定義新型別。
func main() {
type bigint int64
var x bigint = 100
println(x)
}
新型別不是原型別的別名,除擁有相同資料儲存結構外,它們之間沒有任何關係,不會持
有原型別任何資訊。除⾮⺫標型別是未命名型別,否則必須顯式轉換。
x := 1234
var b bigint = bigint(x)
var b2 int64 = int64(b)
var s myslice = []int{1, 2, 3}
var s2 []int = s
// 必須顯式轉換,除⾮是常量。
// 未命名型別,隱式轉換。
test(1) // 常量會被編譯器⾃動轉換。
網址:http://www.qukuailianxueyuan.io/
欲領取造幣技術與全套虛擬機器資料
區塊鏈技術交流QQ群:756146052 備註:CSDN
尹成學院微信:備註:CSDN
test(1) // 常量會被編譯器⾃動轉換。
網址:http://www.qukuailianxueyuan.io/
欲領取造幣技術與全套虛擬機器資料
區塊鏈技術交流QQ群:756146052 備註:CSDN
尹成學院微信:備註:CSDN
相關文章
- 尹成學院golang學習快速筆記(2)表示式Golang筆記
- golang 學習筆記1Golang筆記
- Golang學習筆記(1):包管理Golang筆記
- golang學習筆記(1):安裝&helloworldGolang筆記
- Golang 學習筆記(二) - HTTP 客戶端 - 使用 Client 型別Golang筆記HTTP客戶端client型別
- golang 學習筆記Golang筆記
- Go型別特性-學習筆記Go型別筆記
- JavaScript學習筆記1—快速入門JavaScript筆記
- Spring Boot 學習筆記(1):快速上手Spring Boot筆記
- python學習筆記1—python的基本資料型別Python筆記資料型別
- Redis學習筆記 – 資料型別與API(1)KeyRedis筆記資料型別API
- goLang學習筆記(一)Golang筆記
- goLang學習筆記(二)Golang筆記
- goLang學習筆記(三)Golang筆記
- goLang學習筆記(四)Golang筆記
- 【學習筆記】Golang 切片筆記Golang
- GOLang 學習筆記(一)Golang筆記
- TS學習筆記(一):基本型別筆記型別
- Python 學習筆記——資料型別Python筆記資料型別
- 清華學霸尹成大魔王開創尹成學院www.yinchengxueyuan.com
- Python學習筆記6——動態型別Python筆記型別
- Python學習筆記(一) 資料型別Python筆記資料型別
- Python學習筆記 String型別常用方法Python筆記型別
- C#學習筆記之值型別與引用型別C#筆記型別
- 學習筆記1筆記
- 學習筆記-1筆記
- Python3學習筆記1,基本資料型別-Number、strPython筆記資料型別
- flask文件學習筆記1-快速入門Flask筆記
- 泛型學習筆記泛型筆記
- Golang學習筆記之方法(method)Golang筆記
- Golang學習筆記-1.6 函式Golang筆記函式
- Python 3 學習筆記之——資料型別Python筆記資料型別
- Redis學習筆記(二)——Redis資料型別Redis筆記資料型別
- redis學習筆記2: Redis資料型別Redis筆記資料型別
- Python學習筆記2:基本資料型別Python筆記資料型別
- Java學習筆記8-資料型別Java筆記資料型別
- JavaScript 型別、原型與繼承學習筆記JavaScript型別原型繼承筆記
- golang 學習筆記:第 1 節:GO 語言介紹Golang筆記