尹成学院golang学习快速笔记(1)类型
1.1?變量
?Go?是靜態(tài)類型語?,不能在運(yùn)?期改變變量類型。
?使?關(guān)鍵字?var?定義變量,?動(dòng)初始化為零值。如果提供初始化值,可省略變量類型,由
編譯器?動(dòng)推斷。
var x int var f float32 = 1.6 var s = "abc"在函數(shù)內(nèi)部,可?更簡略的?":="??式定義變量。
func main() {x := 123// 注意檢查,是定義新局部變量,還是修改全局變量。該?式容易造成錯(cuò)誤。}可?次定義多個(gè)變量。
var x, y, z intvar s, n = "abc", 123var (a intb float32)func main() {n, s := 0x1234, "Hello, World!"println(x, s, n)}多變量賦值時(shí),先計(jì)算所有相關(guā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)}編譯器會(huì)將未使?的局部變量當(dāng)做錯(cuò)誤。
注意重新賦值與定義新同名變量的區(qū)別。
?
s := "abc"println(&s)s, y := "hello", 20println(&s, y){s, z := 1000, 30println(&s, z)// 重新賦值: 與前 s 在同?層次的代碼塊中,且有新的變量被定義。// 通常函數(shù)多返回值 err 會(huì)被重復(fù)使?。// 定義新同名變量: 不在同?層次代碼塊。}輸出:
0x2210230f30
0x2210230f30?20
0x2210230f18?30
1.2?常量
常量值必須是編譯期可確定的數(shù)字、字符串、布爾值。
const x, y int = 1, 2const s = "Hello, World!"const (// 多常量初始化// 類型推斷// 常量組a, bc= 10, 100bool = false)func main() {const x = "xxx"// 未使?局部常量不會(huì)引發(fā)編譯錯(cuò)誤。}不?持?1UL、2LL?這樣的類型后綴。
在常量組中,如不提供類型和初始化值,那么視作與上?常量相同。
const (s= "abc"x// x = "abc")?
常量值還可以是?len、cap、unsafe.Sizeof?等編譯期可確定結(jié)果的函數(shù)返回值。
?
?
const (a= "abc"b= len(a)c= unsafe.Sizeof(b))?
如果常量類型?以存儲(chǔ)初始化值,那么不會(huì)引發(fā)溢出錯(cuò)誤。
?
const (a byte = 100// int to byteb int= 1e20// float64 to int, overflows)?
?
?
枚舉
?
關(guān)鍵字?iota?定義常量組中從?0?開始按?計(jì)數(shù)的?增枚舉值。
?
const (Sunday = iota // 0Monday // 1,通常省略后續(xù)?表達(dá)式。Tuesday // 2Wednesday // 3Thursday // 4Friday // 5Saturday // 6) const ( _ KB= iota MB GB TBint64 = 1 << (10 * iota)// iota = 0// iota = 1// 與 KB 表達(dá)式相同,但 iota = 2)在同?常量組中,可以提供多個(gè)?iota,它們各?增?。
?
const (A, B = iota, iota << 10C, D// 0, 0 << 10// 1, 1 << 10)如果?iota??增被打斷,須顯式恢復(fù)。
?
?
const (A= iota// 0B= "c" // 1C= iota// cD // c,與上??相同。E // 4,顯式恢復(fù)。注意計(jì)數(shù)包含了 C、D 兩?。F// 5)?
可通過?定義類型來實(shí)現(xiàn)枚舉類型限制。
?
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) // 常量會(huì)被編譯器?動(dòng)轉(zhuǎn)換。}類型 | ?度 | 默認(rèn)值 | 說明 |
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 | ? | ?以存儲(chǔ)指針的?uint32?或?uint64?整數(shù) |
array | ? | ? | 值類型 |
struct | ? | ? | 值類型 |
string | ? | "" | UTF-8?字符串 |
slice | ? | nil | 引?類型 |
map | ? | nil | 引?類型 |
channel | ? | nil | 引?類型 |
interface | ? | nil | 接? |
function | ? | nil | 函數(shù) |
?
?
?
1.3?基本類型
?
明確字類型命名,?持?Unicode,?持常?數(shù)據(jù)結(jié)構(gòu)。
?持?進(jìn)制、?六進(jìn)制,以及科學(xué)記數(shù)法。標(biāo)準(zhǔn)庫?math?定義了各數(shù)字類型取值范圍。
a, b, c, d := 071, 0x1F, 1e9, math.MinInt16空指針值?nil,???C/C++?NULL。
1.4?引?類型
引?類型包括?slice、map?和?channel。它們有復(fù)雜的內(nèi)部結(jié)構(gòu),除了申請(qǐng)內(nèi)存外,還需
要初始化相關(guān)屬性。
內(nèi)置函數(shù)?new?計(jì)算類型??,為其分配零值內(nèi)存,返回指針。??make?會(huì)被編譯器翻譯
成具體的創(chuàng)建函數(shù),由其分配內(nèi)存和初始化成員結(jié)構(gòu),返回對(duì)象??指針。
?
a := []int{0, 0, 0} a[1] = 10 b := make([]int, 3) b[1] = 10 c := new([]int) c[1] = 10// 提供初始化表達(dá)式。 // makeslice // Error: invalid operation: c[1] (index of type *[]int)1.5?類型轉(zhuǎn)換
不?持隱式類型轉(zhuǎn)換,即便是從窄向?qū)掁D(zhuǎn)換也不?。
var b byte = 100// var n int = bvar n int = int(b)// Error: cannot use b (type byte) as type int in assignment// 顯式轉(zhuǎn)換使?括號(hào)避免優(yōu)先級(jí)錯(cuò)誤。
*Point(p)(*Point)(p)<-chan int(c)(<-chan int)(c)// 相當(dāng)于 *(Point(p))// 相當(dāng)于 <-(chan int(c))同樣不能將其他類型當(dāng)?bool?值使?。
?
a := 100if a {println("true")// Error: non-bool a (type int) used as if condition}?
1.6?字符串
?
字符串是不可變值類型,內(nèi)部?指針指向?UTF-8?字節(jié)數(shù)組。
??默認(rèn)值是空字符串?""。
???索引號(hào)訪問某字節(jié),如?s[i]。
??不能?序號(hào)獲取字節(jié)元素指針,&s[i]??法。
??不可變類型,?法修改字節(jié)數(shù)組。
??字節(jié)數(shù)組尾部不包含?NULL。
?
//runtime.hstruct String{byte*intgostr;len;};使?索引號(hào)問字符?(byte)。
s := "abc"println(s[0] == '\x61', s[1] == 'b', s[2] == 0x63)輸出:
true?true?true
?
?
使??"`"?定義不做轉(zhuǎn)義處理的原始字符串,?持跨?。
輸出:
a
b\r\n\x00
c
?
?
連接跨?字符串時(shí),"+"?必須在上??末尾,否則導(dǎo)致編譯錯(cuò)誤。
?
s := "Hello, " +"World!"s2 := "Hello, "+ "World!"// Error: invalid operation: + untyped string?持?兩個(gè)索引號(hào)返回?串。?串依然指向原字節(jié)數(shù)組,僅修改了指針和?度屬性。
?
?
s := "Hello, World!"s1 := s[:5] // Hellos2 := s[7:]s3 := s[1:5]// Hello// World!// ello?
?
單引號(hào)字符常量表??Unicode?Code?Point,?持?\uFFFF、\U7FFFFFFF、\xFF?格式。
對(duì)應(yīng)?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
?
?
要修改字符串,可先將其轉(zhuǎn)換成?[]rune?或?[]byte,完成后再轉(zhuǎn)換為?string。?論哪種轉(zhuǎn)
換,都會(huì)重新分配內(nèi)存,并復(fù)制字節(jié)數(shù)組。
?
func main() {s := "abcd"bs := []byte(s)bs[1] = 'B'println(string(bs))u := "電腦"us := []rune(u)us[1] = '話'println(string(us))}輸出:
aBcd
電話
?
?
??for?循環(huán)遍歷字符串時(shí),也有?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。
?
?
??默認(rèn)值?nil,沒有?NULL?常量。
??操作符?"&"?取變量地址,"*"?透過指針訪問?標(biāo)對(duì)象。
??不?持指針運(yùn)算,不?持?"->"?運(yùn)算符,直接??"."?訪問?標(biāo)成員。
?
func main() {type data struct{ a int }var d = data{1234}var p *datap = &dfmt.Printf("%p, %v\n", p, p.a)}輸出:
0x2101ef018,?1234
?
?
不能對(duì)指針做加減法等運(yùn)算。
?
x := 1234p := &x // 直接?指針訪問?標(biāo)對(duì)象成員,?須轉(zhuǎn)換。p++// Error: invalid operation: p += 1 (mismatched types *int and int)可以在?unsafe.Pointer?和任意類型指針間進(jìn)?轉(zhuǎn)換。
?
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
?
?
返回局部變量指針是安全的,編譯器會(huì)根據(jù)需要將其分配在?GC?Heap?上。
?
func test() *int {x := 100return &x// 在堆上分配 x 內(nèi)存。但在內(nèi)聯(lián)時(shí),也可能直接分配在?標(biāo)棧。}?
將?Pointer?轉(zhuǎn)換成?uintptr,可變相實(shí)現(xiàn)指針運(yùn)算。
?
?
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?當(dāng)成普通整數(shù)對(duì)象,它?法阻??"關(guān)聯(lián)"?對(duì)象被回收。
1.8??定義類型
可將類型分為命名和未命名兩?類。命名類型包括?bool、int、string?等,??array、
slice、map?等和具體元素類型、?度等有關(guān),屬于未命名類型。
具有相同聲明的未命名類型被視為同?類型。
?
??具有相同基類型的指針。
??具有相同元素類型和?度的?array。
??具有相同元素類型的?slice。
??具有相同鍵值類型的?map。
??具有相同元素類型和傳送?向的?channel。
??具有相同字段序列?(字段名、類型、標(biāo)簽、順序)?的匿名?struct。
??簽名相同?(參數(shù)和返回值,不包括參數(shù)名稱)?的?function。
???法集相同?(?法名、?法簽名相同,和次序?關(guān))?的?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?在全局或函數(shù)內(nèi)定義新類型。
?
func main() {type bigint int64var x bigint = 100println(x)}新類型不是原類型的別名,除擁有相同數(shù)據(jù)存儲(chǔ)結(jié)構(gòu)外,它們之間沒有任何關(guān)系,不會(huì)持
有原類型任何信息。除??標(biāo)類型是未命名類型,否則必須顯式轉(zhuǎn)換。
?
x := 1234var b bigint = bigint(x)var b2 int64 = int64(b)var s myslice = []int{1, 2, 3}var s2 []int = s// 必須顯式轉(zhuǎn)換,除?是常量。// 未命名類型,隱式轉(zhuǎn)換。?
?
test(1)?//?常量會(huì)被編譯器?動(dòng)轉(zhuǎn)換。
網(wǎng)址:http://www.qukuailianxueyuan.io/
欲領(lǐng)取造幣技術(shù)與全套虛擬機(jī)資料
區(qū)塊鏈技術(shù)交流QQ群:756146052??備注:CSDN
尹成學(xué)院微信:備注:CSDN
?
?
?
test(1)?//?常量會(huì)被編譯器?動(dòng)轉(zhuǎn)換。
網(wǎng)址:http://www.qukuailianxueyuan.io/
欲領(lǐng)取造幣技術(shù)與全套虛擬機(jī)資料
區(qū)塊鏈技術(shù)交流QQ群:756146052??備注:CSDN
尹成學(xué)院微信:備注:CSDN
總結(jié)
以上是生活随笔為你收集整理的尹成学院golang学习快速笔记(1)类型的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: JavaWeb企业财务|记账|账单管理系
- 下一篇: 基于欧式聚类的车载路面点云扫描线提取