衍生類型,interface{} , map, [] ,struct等
成都創(chuàng)新互聯(lián)公司是一家專注網(wǎng)站建設(shè)、網(wǎng)絡(luò)營(yíng)銷策劃、成都微信小程序、電子商務(wù)建設(shè)、網(wǎng)絡(luò)推廣、移動(dòng)互聯(lián)開發(fā)、研究、服務(wù)為一體的技術(shù)型公司。公司成立十余年以來,已經(jīng)為上千余家報(bào)廢汽車回收各業(yè)的企業(yè)公司提供互聯(lián)網(wǎng)服務(wù)?,F(xiàn)在,服務(wù)的上千余家客戶與我們一路同行,見證我們的成長(zhǎng);未來,我們一起分享成功的喜悅。
map類似于java的hashmap,python的dict,php的hash array。
常規(guī)的for循環(huán),可以用for k,v :=range m {}. 但在下面清空有一個(gè)坑注意:
著名的map[string]*struct 副本問題
結(jié)果:
Go 中不存在引用傳遞,所有的參數(shù)傳遞都是值傳遞,而map是等同于指針類型的,所以在把map變量傳遞給函數(shù)時(shí),函數(shù)對(duì)map的修改,也會(huì)實(shí)質(zhì)改變map的值。
slice類似于其他語言的數(shù)組(list,array),slice初始化和map一樣,這里不在重復(fù)
除了Pointer數(shù)組外,len表示使用長(zhǎng)度,cap是總?cè)萘?,make([]int, len, cap)可以預(yù)申請(qǐng) 比較大的容量,這樣可以減少容量拓展的消耗,前提是要用到。
cap是計(jì)算切片容量,len是計(jì)算變量長(zhǎng)度的,兩者不一樣。具體例子如下:
結(jié)果:
分析:cap是計(jì)算當(dāng)前slice已分配的容量大小,采用的是預(yù)分配的伙伴算法(當(dāng)容量滿時(shí),拓展分配一倍的容量)。
append是slice非常常用的函數(shù),用于添加數(shù)據(jù)到slice中,但如果使用不好,會(huì)有下面的問題:
預(yù)期是[1 2 3 4 5 6 7 8 9 10], [1 2 3 4 5 6 7 8 9 10 11 12],但實(shí)際結(jié)果是:
注意slice是值傳遞,修改一下:
輸出如下:
== 只能用于判斷常規(guī)數(shù)據(jù)類型,無法使用用于slice和map判斷,用于判斷map和slice可以使用reflect.DeepEqual,這個(gè)函數(shù)用了遞歸來判斷每層的k,v是否一致。
當(dāng)然還有其他方式,比如轉(zhuǎn)換成json,但小心有一些異常的bug,比如html編碼,具體這個(gè)json問題,待后面在分析。
1,go的變量聲明順序是:”先寫變量名,再寫類型名“,此與C/C++的語法孰優(yōu)孰劣,可見下文解釋:
2,go是通過package來組織的(與python類似),只有package名為main的包可以包含main函數(shù),一個(gè)可執(zhí)行程序有且僅有一個(gè)main包,通過import關(guān)鍵字來導(dǎo)入其他非main包。
3,可見性規(guī)則。go語言中,使用大小寫來決定該常量、變量、類型、接口、結(jié)構(gòu)或函數(shù)是否可以被外部包含調(diào)用。根據(jù)約定,函數(shù)名首字母小寫即為private,函數(shù)名首字母大寫即為public。
4,go內(nèi)置關(guān)鍵字(25個(gè)均為小寫)。
5,函數(shù)不用先聲明,即可使用。
6,在函數(shù)內(nèi)部可以通過 := 隱士定義變量。(函數(shù)外必須顯示使用var定義變量)
7,go程序使用UTF-8編碼的純Unicode文本編寫。
8,使用big.Int的陷阱:
9,從技術(shù)層面講,go語言的語句是以分號(hào)分隔的,但這些是由編譯器自動(dòng)添加的,不用手動(dòng)輸入,除非需要在同一行中寫入多個(gè)語句。沒有分號(hào)及只需少量的逗號(hào)和圓括號(hào),使得go語言的程序更容易閱讀。
10,go語言只有一個(gè)循環(huán)結(jié)構(gòu)——for循環(huán)。
11,go里的自增運(yùn)算符只有——“后++”
12,go語言中的slice用法類似python中數(shù)組,關(guān)于slice的詳細(xì)用法可見:
13,函數(shù)也是一個(gè)值,使用匿名函數(shù)返回一個(gè)值。
14,函數(shù)閉包的使用,閉包是一個(gè)匿名函數(shù)值,會(huì)引用到其外部的變量。
大家經(jīng)常用"=="來比較兩個(gè)變量是否相等。但是golang中的"=="有很多細(xì)節(jié)的地方,跟php是不一樣的。很多時(shí)候不能直接用"=="來比較,編譯器會(huì)直接報(bào)錯(cuò)。
golang中基本類型的比較規(guī)則和復(fù)合類型的不一致,先介紹下golang的變量類型:
golang中的基本類型
比較的兩個(gè)變量類型必須相等。而且,golang沒有隱式類型轉(zhuǎn)換,比較的兩個(gè)變量必須類型完全一樣,類型別名也不行。如果要比較,先做類型轉(zhuǎn)換再比較。
復(fù)合類型是逐個(gè)字段,逐個(gè)元素比較的。需要注意的是, array 或者struct中每個(gè)元素必須要是可比較的,如果某個(gè)array的元素 or struct的成員不能比較(比如是后面介紹的slice,map等),則此復(fù)合類型也不能比較。
逐個(gè)成員比較類型和值。每個(gè)對(duì)應(yīng)成員的比較遵循基本類型變量的比較規(guī)則。
但是如果struct中有不可比較的成員類型時(shí):
可以看到,struct中有slice這種不可比較的成員時(shí),整個(gè)struct都不能做比較,即使沒有對(duì)slice那個(gè)成員賦值(slice默認(rèn)值為nil)
slice和map的比較規(guī)則比較奇怪,我們先說普通的變量引用類型val和channel的比較規(guī)則。
引用類型變量存儲(chǔ)的是某個(gè)變量的內(nèi)存地址。所以引用類型變量的比較,判斷的是這兩個(gè)引用類型存儲(chǔ)的是不是同一個(gè)變量。
上面看起來比較廢話,但是得理解引用類型的含義。不然對(duì)判斷規(guī)則還是不清楚。
slice類型不可比較,只能與零值nil做比較。
關(guān)于slice類型不可比較的原因,后面會(huì)專門寫文章做討論。
map類型和slice一樣,不能比較,只能與nil做比較。
接口類型的變量,包含該接口變量存儲(chǔ)的值和值的類型兩部分組成,分別稱為接口的動(dòng)態(tài)類型和動(dòng)態(tài)值。 只有動(dòng)態(tài)類型和動(dòng)態(tài)值都相同時(shí),兩個(gè)接口變量才相同:
而且接口的動(dòng)態(tài)類型必須要是可比較的,如果不能比較(比如slice,map),則運(yùn)行時(shí)會(huì)報(bào)panic。因?yàn)榫幾g器在編譯時(shí)無法獲取接口的動(dòng)態(tài)類型,所以編譯能通過,但是運(yùn)行時(shí)直接panic:
golang的func作為一等公民,也是一種類型,而且不可比較
上面說過,map和slice是不可比較類型,但是有沒有特殊的方法來對(duì)slice和map做比較呢,有
reflect.DeepEqual函數(shù)可以用來比較兩個(gè)任意類型的變量
對(duì)map類型做比較:
對(duì)slice類型做比較:
對(duì)struct類型做比較:
可以發(fā)現(xiàn),只要變量的類型和值相同的話,reflect.DeepEqual比較的結(jié)果就為true
直接看用例:
結(jié)果為:
1, golang的類型再定義和類型別名
2,golang的slice和map為什么不可以比較
1,
2,
3,
文章名稱:go語言變量的規(guī)則 go 函數(shù)變量
瀏覽地址:http://jinyejixie.com/article8/hpdeip.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供Google、網(wǎng)站策劃、微信小程序、商城網(wǎng)站、、網(wǎng)站排名
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)