日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

go语言学习(基本数据类型)

發(fā)布時(shí)間:2024/4/14 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 go语言学习(基本数据类型) 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

值類(lèi)型:

int/uint :根據(jù)系統(tǒng)確定是32還是64位。此外還有int8/uint8、int16/uint16、int32/uint32、int64/uint64

byte:字節(jié)型,相當(dāng)于uint8。

float:go語(yǔ)言中沒(méi)有double型,因?yàn)橐呀?jīng)有了float32/float64,分別精確到小數(shù)點(diǎn)后面7、15位。

uintptr:保存32bit或64bit指針,應(yīng)該是保存指針的地址

數(shù)組array:

數(shù)組是有類(lèi)型的,比如var a [10]int= [10]int{1},a的類(lèi)型為[10]int。

數(shù)組之間可以比較相等==或者不相等(!=),前提是類(lèi)型相同。如果數(shù)組間類(lèi)型相同且內(nèi)容依次都一致,那么兩個(gè)數(shù)組相等;如果兩個(gè)數(shù)組類(lèi)型相同,內(nèi)容不一致,那么數(shù)組不相等。

數(shù)組間賦值是值拷貝,會(huì)拷貝整個(gè)數(shù)組的所有元素給另一個(gè)數(shù)組,而不是引用拷貝,這點(diǎn)和C很不一樣!!!

string

有地方說(shuō)string是不可變的。這里要從string的內(nèi)部結(jié)構(gòu)說(shuō)起:

1 type StringHeader struct { 2 Data uintptr 3 Len int 4 }

?string內(nèi)部是一個(gè)指向某塊內(nèi)存的指針,加上內(nèi)存塊的長(zhǎng)度。這里說(shuō)的string不可變指的是uintptr指向的內(nèi)存塊的內(nèi)容不可變,但是其指向可以變,用C語(yǔ)言描述一下就是:

const T *uintptr;

?

?

struct

struct是值類(lèi)型。struct的聲明和初始化如下:

1 type Person struct { 2 Name string 3 Age int 4 }//struct聲明 5 6 a := Person{ 7 Age: 1, 8 Name: "hao", 9 }//直接初始化賦值,每個(gè)賦值語(yǔ)句后面要有逗號(hào) 10 11 b := Person{} //空結(jié)構(gòu)體 View Code

?

go語(yǔ)言中沒(méi)有繼承的概念,只有組合的概念,下面是個(gè)小例子:

1 type Person struct { 2 Name string 3 Age int 4 } 5 6 type teacher struct { 7 Person 8 field string 9 } 10 11 type student struct { 12 Person 13 score int 14 } 15 16 func main() { 17 a := student{ 18 score: 100, 19 Person: Person{"guhao", 18}, 20 } 21 fmt.Println(a) 22 }

struct中的method

go沒(méi)有class,只有struct。但是struct中提供了method方法,但不支持重載。寫(xiě)法與函數(shù)類(lèi)似,這樣一個(gè)struct就和method綁定了起來(lái)。method可以訪問(wèn)struct的所有字段,事實(shí)上go語(yǔ)言struct字段的可見(jiàn)性是針對(duì)真?zhèn)€package而言的。

1 type A struct { 2 Name string 3 } 4 5 type B struct { 6 Name string 7 } 8 9 func main() { 10 a := A{ 11 Name: "gu", 12 } 13 a.Print("hao") 14 } 15 16 func (a A) Print(arg string) { //(a A)表示接收者,arg代表方法的參數(shù) 17 fmt.Println(a.Name, arg) 18 }

?基礎(chǔ)類(lèi)型起別名

?go語(yǔ)言中可以給基礎(chǔ)類(lèi)型起別名,類(lèi)似于C語(yǔ)言一樣。下面的例子是給int起了個(gè)別名TZ,然后給這個(gè)別名綁定了print方法:

1 type TZ int 2 3 func (a *TZ) print() { 4 fmt.Println("TZ:", *a) 5 } 6 func main() { 7 var a TZ = 100 8 a.print() 9 10 var b int 11 b = a //錯(cuò)誤 12 b.print() //錯(cuò)誤 13 }

雖然TZ是int的別名,但兩者不能直接賦值,需要顯式的類(lèi)型強(qiáng)制轉(zhuǎn)換。go語(yǔ)言將這兩者視為不同的類(lèi)型。

1 var b int = 99 2 a = TZ(b) 3 a.print()

?

?

?

引用類(lèi)型:

引用類(lèi)型有三種:slice\map和channel

slice

slice其實(shí)是一個(gè)結(jié)構(gòu)體,其中包含了指向底層數(shù)組的指針、長(zhǎng)度、容量。所以改變slice的值也會(huì)改變對(duì)應(yīng)的指向的底層數(shù)組。

slice不支持==,或者!=

?

map

map內(nèi)部實(shí)現(xiàn)是hashtable, 定義如下m:=make(map[int]string),每一級(jí)map需要單獨(dú)初始化,否則直接用對(duì)二級(jí)map賦值會(huì)報(bào)錯(cuò),而且是運(yùn)行時(shí)候的錯(cuò)誤,編譯時(shí)無(wú)法發(fā)現(xiàn)。

1 func main() { 2 m := make(map[int]map[int]string) 3 a, ok := m[2][1] 4 if !ok { 5 m[2] = make(map[int]string) 6 } 7 a = "A" 8 fmt.Println(a, ok) 9 }

此外,map是引用類(lèi)型,需要用make定義。而且map自動(dòng)擴(kuò)容,我需要學(xué)習(xí)。map的key必須支持==和!=操作(廢話,不然怎么做通過(guò)key去查找)。

channel

?

接口類(lèi)型

interface

函數(shù)類(lèi)型

func:函數(shù)也是一種類(lèi)型,因?yàn)間o語(yǔ)言的函數(shù)可以賦值給變量。不支持嵌套,重載和默認(rèn)參數(shù)。支持closure。

1 func closure(x int) func(int) int { 2 fmt.Printf("%p\n", &x) 3 return func(y int) int { 4 fmt.Printf("%p\n", &x) 5 return x + y 6 } 7 } 8 9 func main() { 10 x := 1 11 fc := closure(x) 12 fc(100) 13 fc(200) 14 }

我打印了三次調(diào)用的x的地址,打印的結(jié)果顯示三次調(diào)用用到的x的值都是一樣的,所以閉包對(duì)的x不是值拷貝,而是引用(應(yīng)該是為了節(jié)約空間)。

defer語(yǔ)句

go語(yǔ)言特有的,執(zhí)行順序和定義順序相反,先定義的語(yǔ)句后執(zhí)行。

此外還支持panic和recover

?panic和recover

1 func A() { 2 fmt.Println("A") 3 } 4 5 func B() { 6 defer func() { 7 if err := recover(); err != nil { 8 fmt.Println("recover in B") 9 } 10 }() 11 panic("Panic in B") 12 } 13 14 func C() { 15 fmt.Println("C") 16 } 17 18 func main() { 19 A() 20 B() 21 C() 22 }

panic會(huì)導(dǎo)致程序中斷,執(zhí)行完了panic之后就不執(zhí)行其他語(yǔ)句了,除非我們?cè)趐anic執(zhí)行前先注冊(cè)了defer語(yǔ)句。因此recover登場(chǎng)了。recover必須和defer一起使用。可以幫助程序恢復(fù)執(zhí)行。以上代碼執(zhí)行結(jié)構(gòu)如下:

?

類(lèi)型轉(zhuǎn)換只能顯式轉(zhuǎn)換,不能隱式轉(zhuǎn)換

1 var a int = 3 2 var f float32 = float32(a)

?

?枚舉類(lèi)型

枚舉類(lèi)型必須定義在const塊內(nèi).

1、const塊內(nèi)默認(rèn)下一條使用上一條語(yǔ)句

2、枚舉值與iota出現(xiàn)的次數(shù)無(wú)關(guān),與出現(xiàn)的位置有關(guān):iota出現(xiàn)的位置代表了其值,默認(rèn)從0開(kāi)始。

1 const ( 2 a = 'A' 3 b 4 c 5 d = iota 6 e = 'B' 7 f = iota 8 g 9 ) 10 11 func main() { 12 fmt.Println(a) //輸出65 13 fmt.Println(b) //輸出65 14 fmt.Println(c) //輸出65 15 fmt.Println(d) //輸出3 16 fmt.Println(e) //輸出66 17 fmt.Println(f) //輸出5 18 fmt.Println(g) //輸出6 19 }

?運(yùn)算符

有算術(shù)運(yùn)算符和邏輯運(yùn)算符、位運(yùn)算符,寫(xiě)法和C語(yǔ)言一致。

多了一個(gè)專(zhuān)門(mén)為channel準(zhǔn)備的運(yùn)算符<-

A

recover in B

C

?

new和make

new返回的是指針,不會(huì)初始化變量,只是把新申請(qǐng)的空間內(nèi)容值為零。用C語(yǔ)言寫(xiě)類(lèi)似下面:

1 T *obj=(T*)malloc(sizeof(T)); 2 memset(obj, 0, sizeof(T));

但并不是很準(zhǔn)確,因?yàn)間o語(yǔ)言中不同變量類(lèi)型的零值不一樣,比如bool的零值為false,int為零值為0,string的零值為空串,指針的零值是nil。所以下面這段代碼p==nil

var p *[]int = new([]int)

?

內(nèi)建函數(shù)make(T,?args)與new(T)的用途不一樣。它只用來(lái)創(chuàng)建slice,map和channel,并且返回一個(gè)初始化的(而不是置零),類(lèi)型為T(mén)的值(而不是*T)。之所以有所不同,是因?yàn)檫@三個(gè)類(lèi)型的背后引用了使用前必須初始化的數(shù)據(jù)結(jié)構(gòu)。例如,slice是一個(gè)三元描述符,包含一個(gè)指向數(shù)據(jù)(在數(shù)組中)的指針,長(zhǎng)度,以及容量,在這些項(xiàng)被初始化之前,slice都是nil的。對(duì)于slice,map和channel,make初始化這些內(nèi)部數(shù)據(jù)結(jié)構(gòu),并準(zhǔn)備好可用的值。

?

內(nèi)存管理

特別值得注意的是,局部變量不是所有的都分配在stack中(new出來(lái)的對(duì)象當(dāng)然在heap上),如果一個(gè)函數(shù)的局部變量返回后依然被使用,那么這個(gè)變量分配在heap上,而不是stack上。

?

轉(zhuǎn)載于:https://www.cnblogs.com/howo/p/9033807.html

總結(jié)

以上是生活随笔為你收集整理的go语言学习(基本数据类型)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。