尹成学院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 intvar s, n = "abc", 123var (a intb float32)func main() {n, s := 0x1234, "Hello, World!"println(x, s, n)}多變量賦值時,先計算所有相關值,然后再從左到右依次賦值。
data, i := [3]int{0, 1, 2}, 0i, 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)}編譯器會將未使?的局部變量當做錯誤。
注意重新賦值與定義新同名變量的區別。
?
s := "abc"println(&s)s, y := "hello", 20println(&s, y){s, z := 1000, 30println(&s, z)// 重新賦值: 與前 s 在同?層次的代碼塊中,且有新的變量被定義。// 通常函數多返回值 err 會被重復使?。// 定義新同名變量: 不在同?層次代碼塊。}輸出:
0x2210230f30
0x2210230f30?20
0x2210230f18?30
1.2?常量
常量值必須是編譯期可確定的數字、字符串、布爾值。
const x, y int = 1, 2const s = "Hello, World!"const (// 多常量初始化// 類型推斷// 常量組a, bc= 10, 100bool = 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 byteb int= 1e20// float64 to int, overflows)?
?
?
枚舉
?
關鍵字?iota?定義常量組中從?0?開始按?計數的?增枚舉值。
?
const (Sunday = iota // 0Monday // 1,通常省略后續?表達式。Tuesday // 2Wednesday // 3Thursday // 4Friday // 5Saturday // 6) const ( _ KB= iota MB GB TBint64 = 1 << (10 * iota)// iota = 0// iota = 1// 與 KB 表達式相同,但 iota = 2)在同?常量組中,可以提供多個?iota,它們各?增?。
?
const (A, B = iota, iota << 10C, D// 0, 0 << 10// 1, 1 << 10)如果?iota??增被打斷,須顯式恢復。
?
?
const (A= iota// 0B= "c" // 1C= iota// cD // c,與上??相同。E // 4,顯式恢復。注意計數包含了 C、D 兩?。F// 5)?
可通過?定義類型來實現枚舉類型限制。
?
type Color intconst (Black Color = iotaRedBlue)func test(c Color) {}func main() {c := Blacktest(c)x := 1test(x) // Error: cannot use x (type int) as type Color in function argumenttest(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 = bvar 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 := 100if a {println("true")// Error: non-bool a (type int) used as if condition}?
1.6?字符串
?
字符串是不可變值類型,內部?指針指向?UTF-8?字節數組。
??默認值是空字符串?""。
???索引號訪問某字節,如?s[i]。
??不能?序號獲取字節元素指針,&s[i]??法。
??不可變類型,?法修改字節數組。
??字節數組尾部不包含?NULL。
?
//runtime.hstruct String{byte*intgostr;len;};使?索引號問字符?(byte)。
s := "abc"println(s[0] == '\x61', s[1] == 'b', s[2] == 0x63)輸出:
true?true?true
?
?
使??"`"?定義不做轉義處理的原始字符串,?持跨?。
輸出:
a
b\r\n\x00
c
?
?
連接跨?字符串時,"+"?必須在上??末尾,否則導致編譯錯誤。
?
s := "Hello, " +"World!"s2 := "Hello, "+ "World!"// Error: invalid operation: + untyped string?持?兩個索引號返回?串。?串依然指向原字節數組,僅修改了指針和?度屬性。
?
?
s := "Hello, World!"s1 := s[:5] // Hellos2 := 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 *datap = &dfmt.Printf("%p, %v\n", p, p.a)}輸出:
0x2101ef018,?1234
?
?
不能對指針做加減法等運算。
?
x := 1234p := &x // 直接?指針訪問?標對象成員,?須轉換。p++// Error: invalid operation: p += 1 (mismatched types *int and int)可以在?unsafe.Pointer?和任意類型指針間進?轉換。
?
func main() {x := 0x12345678p := 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 := 100return &x// 在堆上分配 x 內存。但在內聯時,也可能直接分配在?標棧。}?
將?Pointer?轉換成?uintptr,可變相實現指針運算。
?
?
func main() {d := struct {sxstringint}{"abc", 100}p := uintptr(unsafe.Pointer(&d))p += unsafe.Offsetof(d.x)// *struct -> Pointer -> uintptr// uintptr + offsetp2 := unsafe.Pointer(p)px := (*int)(p2)*px = 200fmt.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 assignmentb = a?
?
可??type?在全局或函數內定義新類型。
?
func main() {type bigint int64var x bigint = 100println(x)}新類型不是原類型的別名,除擁有相同數據存儲結構外,它們之間沒有任何關系,不會持
有原類型任何信息。除??標類型是未命名類型,否則必須顯式轉換。
?
x := 1234var 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学习快速笔记(1)类型的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: JavaWeb企业财务|记账|账单管理系
- 下一篇: 基于欧式聚类的车载路面点云扫描线提取