隊(duì)列的概念在 順序隊(duì)列 中,而使用循環(huán)隊(duì)列的目的主要是規(guī)避假溢出造成的空間浪費(fèi),在使用循環(huán)隊(duì)列處理假溢出時(shí),主要有三種解決方案
按需策劃設(shè)計(jì)可以根據(jù)自己的需求進(jìn)行定制,成都做網(wǎng)站、成都網(wǎng)站制作構(gòu)思過(guò)程中功能建設(shè)理應(yīng)排到主要部位公司成都做網(wǎng)站、成都網(wǎng)站制作的運(yùn)用實(shí)際效果公司網(wǎng)站制作網(wǎng)站建立與制做的實(shí)際意義
本文提供后兩種解決方案。
順序隊(duì)和循環(huán)隊(duì)列是一種特殊的線性表,與順序棧類(lèi)似,都是使用一組地址連續(xù)的存儲(chǔ)單元依次存放自隊(duì)頭到隊(duì)尾的數(shù)據(jù)元素,同時(shí)附設(shè)隊(duì)頭(front)和隊(duì)尾(rear)兩個(gè)指針,但我們要明白一點(diǎn),這個(gè)指針并不是指針變量,而是用來(lái)表示數(shù)組當(dāng)中元素下標(biāo)的位置。
本文使用切片來(lái)完成的循環(huán)隊(duì)列,由于一開(kāi)始使用三個(gè)參數(shù)的make關(guān)鍵字創(chuàng)建切片,在輸出的結(jié)果中不包含nil值(看起來(lái)很舒服),而且在驗(yàn)證的過(guò)程中發(fā)現(xiàn)使用append()函數(shù)時(shí)切片內(nèi)置的cap會(huì)發(fā)生變化,在消除了種種障礙后得到了一個(gè)四不像的循環(huán)隊(duì)列,即設(shè)置的指針是順序隊(duì)列的指針,但實(shí)際上進(jìn)行的操作是順序隊(duì)列的操作。最后是對(duì)make()函數(shù)和append()函數(shù)的一些使用體驗(yàn)和小結(jié),隊(duì)列的應(yīng)用放在鏈隊(duì)好了。
官方描述(片段)
即切片是一個(gè)抽象層,底層是對(duì)數(shù)組的引用。
當(dāng)我們使用
構(gòu)建出來(lái)的切片的每個(gè)位置的值都被賦為interface類(lèi)型的初始值nil,但是nil值也是有大小的。
而使用
來(lái)進(jìn)行初始化時(shí),雖然生成的切片中不包含nil值,但是無(wú)法通過(guò)設(shè)置的指針變量來(lái)完成入隊(duì)和出隊(duì)的操作,只能使用append()函數(shù)來(lái)進(jìn)行操作
在go語(yǔ)言中,切片是一片連續(xù)的內(nèi)存空間加上長(zhǎng)度與容量的標(biāo)識(shí),比數(shù)組更為常用。使用 append 關(guān)鍵字向切片中追加元素也是常見(jiàn)的切片操作
正是基于此,在使用go語(yǔ)言完成循環(huán)隊(duì)列時(shí),首先想到的就是使用make(type, len, cap)關(guān)鍵字方式完成切片初始化,然后使用append()函數(shù)來(lái)操作該切片,但這一方式出現(xiàn)了很多問(wèn)題。在使用append()函數(shù)時(shí),切片的cap可能會(huì)發(fā)生變化,用不好就會(huì)發(fā)生擴(kuò)容或收縮。最終造成的結(jié)果是一個(gè)四不像的結(jié)果,入隊(duì)和出隊(duì)操作變得與指針變量無(wú)關(guān),失去了作為循環(huán)隊(duì)列的意義,用在順序隊(duì)列還算合適。
參考博客:
Go語(yǔ)言中的Nil
Golang之nil
Go 語(yǔ)言設(shè)計(jì)與實(shí)現(xiàn)
作為C語(yǔ)言家族的一員,go和c一樣也支持結(jié)構(gòu)體??梢灶?lèi)比于java的一個(gè)POJO。
在學(xué)習(xí)定義結(jié)構(gòu)體之前,先學(xué)習(xí)下定義一個(gè)新類(lèi)型。
新類(lèi)型 T1 是基于 Go 原生類(lèi)型 int 定義的新自定義類(lèi)型,而新類(lèi)型 T2 則是 基于剛剛定義的類(lèi)型 T1,定義的新類(lèi)型。
這里要引入一個(gè)底層類(lèi)型的概念。
如果一個(gè)新類(lèi)型是基于某個(gè) Go 原生類(lèi)型定義的, 那么我們就叫 Go 原生類(lèi)型為新類(lèi)型的底層類(lèi)型
在上面的例子中,int就是T1的底層類(lèi)型。
但是T1不是T2的底層類(lèi)型,只有原生類(lèi)型才可以作為底層類(lèi)型,所以T2的底層類(lèi)型還是int
底層類(lèi)型是很重要的,因?yàn)閷?duì)兩個(gè)變量進(jìn)行顯式的類(lèi)型轉(zhuǎn)換,只有底層類(lèi)型相同的變量間才能相互轉(zhuǎn)換。底層類(lèi)型是判斷兩個(gè)類(lèi)型本質(zhì)上是否相同的根本。
這種類(lèi)型定義方式通常用在 項(xiàng)目的漸進(jìn)式重構(gòu),還有對(duì)已有包的二次封裝方面
類(lèi)型別名表示新類(lèi)型和原類(lèi)型完全等價(jià),實(shí)際上就是同一種類(lèi)型。只不過(guò)名字不同而已。
一般我們都是定義一個(gè)有名的結(jié)構(gòu)體。
字段名的大小寫(xiě)決定了字段是否包外可用。只有大寫(xiě)的字段可以被包外引用。
還有一個(gè)點(diǎn)提一下
如果換行來(lái)寫(xiě)
Age: 66,后面這個(gè)都好不能省略
還有一個(gè)點(diǎn),觀察e3的賦值
new返回的是一個(gè)指針。然后指針可以直接點(diǎn)號(hào)賦值。這說(shuō)明go默認(rèn)進(jìn)行了取值操作
e3.Age 等價(jià)于 (*e3).Age
如上定義了一個(gè)空的結(jié)構(gòu)體Empty。打印了元素e的內(nèi)存大小是0。
有什么用呢?
基于空結(jié)構(gòu)體類(lèi)型內(nèi)存零開(kāi)銷(xiāo)這樣的特性,我們?cè)谌粘?Go 開(kāi)發(fā)中會(huì)經(jīng)常使用空 結(jié)構(gòu)體類(lèi)型元素,作為一種“事件”信息進(jìn)行 Goroutine 之間的通信
這種以空結(jié)構(gòu)體為元素類(lèi)建立的 channel,是目前能實(shí)現(xiàn)的、內(nèi)存占用最小的 Goroutine 間通信方式。
這種形式需要說(shuō)的是幾個(gè)語(yǔ)法糖。
語(yǔ)法糖1:
對(duì)于結(jié)構(gòu)體字段,可以省略字段名,只寫(xiě)結(jié)構(gòu)體名。默認(rèn)字段名就是結(jié)構(gòu)體名
這種方式稱(chēng)為 嵌入字段
語(yǔ)法糖2:
如果是以嵌入字段形式寫(xiě)的結(jié)構(gòu)體
可以省略嵌入的Reader字段,而直接訪問(wèn)ReaderName
此時(shí)book是一個(gè)各個(gè)屬性全是對(duì)應(yīng)類(lèi)型零值的一個(gè)實(shí)例。不是nil。這種情況在Go中稱(chēng)為零值可用。不像java會(huì)導(dǎo)致npe
結(jié)構(gòu)體定義時(shí)可以在字段后面追加標(biāo)簽說(shuō)明。
tag的格式為反單引號(hào)
tag的作用是可以使用[反射]來(lái)檢視字段的標(biāo)簽信息。
具體的作用還要看使用的場(chǎng)景。
比如這里的tag是為了幫助 encoding/json 標(biāo)準(zhǔn)包在解析對(duì)象時(shí)可以利用的規(guī)則。比如omitempty表示該字段沒(méi)有值就不打印出來(lái)。
很多語(yǔ)言都是采用 ~ 作為按位取反運(yùn)算符,Go 里面采用的是 ^ 。
如果作為二元運(yùn)算符,^ 表示按位異或,即:對(duì)應(yīng)位相同為 0,相異為 1。
操作符 ^,按位置零,例如:z = x ^ y,表示如果 y 中的 bit 位為 1,則 z 對(duì)應(yīng) bit 位為 0,否則 z 對(duì)應(yīng) bit 位等于 x 中相應(yīng)的 bit 位的值。
對(duì)于有符號(hào)的整數(shù)來(lái)說(shuō),是按照補(bǔ)碼進(jìn)行取反操作的(快速計(jì)算方法:對(duì)數(shù) a 取反,結(jié)果為 -(a+1) ),對(duì)于無(wú)符號(hào)整數(shù)來(lái)說(shuō)就是按位取反
計(jì)算過(guò)程
以3為例? 3在內(nèi)存中補(bǔ)碼為 0*** 0011
取反? ? ? ? ? ? 1*** 1100
-1操作? ? ? ? ? 1*** 1011
除符號(hào)位取反? ? 1*** 0100 結(jié)果為-4
-------------------------------------------
以9為例 9在內(nèi)存中補(bǔ)碼為 0*** 1001
取反? ? ? ? ? ? 1*** 0110
-1操作? ? ? ? ? 1*** 0101
除符號(hào)位取反? ? 1*** 1010 結(jié)果為-10
-------------------------------------------
以-5為例 -5在內(nèi)存中為的補(bǔ)碼為 1*** 1011
為什么呢
-5源碼? ? ? ? ? 1*** 0101
除符號(hào)取反? ? ? 1*** 1010
+1操作? ? ? ? ? 1*** 1011
-------------------------------------------
那么-5取反怎么算
補(bǔ)碼 1***1011取反為 0***0100
因?yàn)榉?hào)位為0,所以是正數(shù)了,正數(shù)的補(bǔ)碼反碼源碼都是一個(gè),所以是4
===================================
再看-1
-1源碼? ? ? ? ? 1*** 0001
除符號(hào)取反? ? ? 1*** 1110
+1操作? ? ? ? ? 1*** 1111
補(bǔ)碼 1*** 1111 取反為 0*** 0000
因?yàn)榉?hào)位為0,所以是正數(shù)了,正數(shù)的補(bǔ)碼反碼源碼都是一個(gè),所以是0
go語(yǔ)言取反輸出的例子看這里
書(shū)寫(xiě)合格的程序代碼是進(jìn)行程序設(shè)計(jì)的根本。只有熟練地掌握了這些內(nèi)容,在以后的編程中才不會(huì)捉襟見(jiàn)肘。編程的語(yǔ)法就和我們平時(shí)說(shuō)話一樣,是采用大家公認(rèn)的詞匯以及詞匯的組織規(guī)則來(lái)表達(dá)自己。
VB的程序代碼由語(yǔ)句、常數(shù)和聲明等部分組成,使用最為頻繁的語(yǔ)句就是賦值語(yǔ)句。使用賦值語(yǔ)句可以在程序運(yùn)行的過(guò)程中改變對(duì)象的屬性和變量的值。它的語(yǔ)法很簡(jiǎn)單:
對(duì)象.屬性或變量=表達(dá)式
這個(gè)語(yǔ)句的含義就是把等號(hào)右邊表達(dá)式的值傳送給等號(hào)左邊的變量或者對(duì)象的屬性。
希望我能幫助你解疑釋惑。
go語(yǔ)言中的if語(yǔ)句和其他語(yǔ)言中的類(lèi)似,都是根據(jù)給定的條件表達(dá)式運(yùn)算結(jié)果來(lái),判斷執(zhí)行流程。
注意:在go語(yǔ)言中 布爾表達(dá)式不用使用括號(hào)。
根據(jù)布爾值flag判斷
程序運(yùn)行結(jié)果
初始變量可以聲明在布爾表達(dá)式里面,注意它的作用域
程序運(yùn)行結(jié)果
注意:不能使用0或非0表示真假
go語(yǔ)言if語(yǔ)句使用提示:
go語(yǔ)言中的if else語(yǔ)句可以根據(jù)給定條件二選一。
比較兩個(gè)數(shù)的大小
運(yùn)行結(jié)果
判斷一個(gè)數(shù)是奇數(shù)還是偶數(shù)
運(yùn)行結(jié)果
判斷一個(gè)人是否成年
運(yùn)行結(jié)果
特殊寫(xiě)法,在if前面添加執(zhí)行語(yǔ)句
運(yùn)行結(jié)果
go語(yǔ)言if語(yǔ)句使用提示:
go語(yǔ)言if語(yǔ)句可以進(jìn)行多重嵌套使用,進(jìn)行多重判斷。
根據(jù)分?jǐn)?shù)判斷等級(jí)
運(yùn)行結(jié)果
同樣也可以寫(xiě)成這樣
運(yùn)行結(jié)果
輸入星期幾的第一個(gè)字母來(lái)判斷一下是星期幾,如果第一個(gè)字母一樣,則繼續(xù)判斷第二個(gè)字母
運(yùn)行結(jié)果
go語(yǔ)言if語(yǔ)句可以嵌套多級(jí)進(jìn)行判斷。
判斷三個(gè)數(shù)的大小
運(yùn)行結(jié)果
判斷男生還是女生,還有是否成年
運(yùn)行結(jié)果