對(duì)于切片的順序遍歷,一般使用 range 就可以了。
成都創(chuàng)新互聯(lián)專(zhuān)注于龍川網(wǎng)站建設(shè)服務(wù)及定制,我們擁有豐富的企業(yè)做網(wǎng)站經(jīng)驗(yàn)。 熱誠(chéng)為您提供龍川營(yíng)銷(xiāo)型網(wǎng)站建設(shè),龍川網(wǎng)站制作、龍川網(wǎng)頁(yè)設(shè)計(jì)、龍川網(wǎng)站官網(wǎng)定制、成都微信小程序服務(wù),打造龍川網(wǎng)絡(luò)公司原創(chuàng)品牌,更為您提供龍川網(wǎng)站排名全網(wǎng)營(yíng)銷(xiāo)落地服務(wù)。
這里有一個(gè)問(wèn)題需要注意一下,如果這里的切片nums不是基本數(shù)據(jù)類(lèi)型而是結(jié)構(gòu)體。range遍歷出來(lái)的value值是拷貝值而并非原結(jié)構(gòu)體,修改value中的值不會(huì)改變?cè)衅械闹?。如果要遍歷修改,可以將切片的結(jié)構(gòu)體改為指針,或都索引來(lái)取值。
一般情況下逆序遍歷思路就是for size-1到0.
二般的也可以使用range來(lái)遍歷
圖例如下:
結(jié)果應(yīng)該是分別是:
廣度優(yōu)先: a - b - c - d - f - e - g
先序遍歷: a - b - d - e - f - g - c
中序遍歷: e - d - b - g - f - a - c
后序遍歷: e - d - g - f - b - c - a
結(jié)果存在result里面,如果不存可以少一層變量
這個(gè)地方強(qiáng)烈建議讀一下下面的第一個(gè)鏈接,我遵照著那篇文章實(shí)現(xiàn)的,只是用Go改寫(xiě)了而已。
首先定義一個(gè)數(shù)據(jù)結(jié)構(gòu),用來(lái)存儲(chǔ)一些Node的信息。
這里是可以運(yùn)行的,但是總會(huì)拋出一個(gè)數(shù)組越界的錯(cuò)誤,我看了半天也沒(méi)看出來(lái)哪里有問(wèn)題,Mac版的devel我這邊又有bug,沒(méi)用起來(lái)。至少思路對(duì)了,我后面再看一下哪里的問(wèn)題。(感謝 @RiXu 指正)
首先說(shuō)一下go中的字符串類(lèi)型:
字符串就是一串固定長(zhǎng)度的字符連接起來(lái)的字符序列。Go的字符串是由單個(gè)字節(jié)連接起來(lái)的。Go語(yǔ)言的字符串的字節(jié)使用UTF-8編碼標(biāo)識(shí)Unicode文本。
下面介紹字符串的三種遍歷方式,根據(jù)實(shí)際情況選擇即可。
該遍歷方式==缺點(diǎn)==:遍歷是按照字節(jié)遍歷,因此如果有中文等非英文字符,就會(huì)出現(xiàn)亂碼,比如要遍歷"abc北京"這個(gè)字符串,效果如下:
可見(jiàn)這不是我們想要的效果,根據(jù)utf-8中文編碼規(guī)則,我們要str[3]str[4]str[5]三個(gè)字節(jié)合起來(lái)組成“北”字及 str[6]str[7]str[8]合起來(lái)組成“京”字。由此引出下面第二種遍歷方法。
該方式是按照字符遍歷的,所以不會(huì)出現(xiàn)亂碼,如下:
運(yùn)行結(jié)果:
從圖中可以看到第二個(gè)漢子“京”的開(kāi)始下標(biāo)是6,直接跳過(guò)了4和5,可見(jiàn)確實(shí)依照utf8編碼方式將三個(gè)字節(jié)組合成了一個(gè)漢字,str[3]-str[5]組合成“北”字,str[6]-str[8]組合成了“京”字。
由于下標(biāo)的不確定性,所以引出了下面的遍歷方式。
1 可以先將字符串轉(zhuǎn)成 []rune 切片
2 再用常規(guī)方法進(jìn)行遍歷
運(yùn)行效果:
由此可見(jiàn)下標(biāo)是按1遞增的,沒(méi)有產(chǎn)生跳躍現(xiàn)象。
Go 原生的 pkg 中有一些核心的 interface ,其中 io.Reader/Writer 是比較常用的接口。很多原生的結(jié)構(gòu)都圍繞這個(gè)系列的接口展開(kāi),在實(shí)際的開(kāi)發(fā)過(guò)程中,你會(huì)發(fā)現(xiàn)通過(guò)這個(gè)接口可以在多種不同的io類(lèi)型之間進(jìn)行過(guò)渡和轉(zhuǎn)化。本文結(jié)合實(shí)際場(chǎng)景來(lái)總結(jié)一番。
圍繞 io.Reader/Writer ,有幾個(gè)常用的實(shí)現(xiàn):
這些實(shí)現(xiàn)對(duì)于初學(xué)者來(lái)說(shuō)其實(shí)比較難去記憶,在遇到實(shí)際問(wèn)題的時(shí)候更是一臉蒙圈,不知如何是好。下面用實(shí)際的場(chǎng)景來(lái)舉例
encoding/base64 包中:
這個(gè)用來(lái)做 base64 編碼,但是仔細(xì)觀(guān)察發(fā)現(xiàn),它需要一個(gè)io.Writer作為輸出目標(biāo),并用返回的 WriteCloser 的Write方法將結(jié)果寫(xiě)入目標(biāo),下面是Go官方文檔的例子
這個(gè)例子是將結(jié)果寫(xiě)入到 Stdout ,如果我們希望得到一個(gè)字符串呢?觀(guān)察上面的圖,不然發(fā)現(xiàn)可以用bytes.Buffer作為目標(biāo) io.Writer :
這種場(chǎng)景經(jīng)常用在基于字節(jié)的協(xié)議上,比如有一個(gè)具有固定長(zhǎng)度的結(jié)構(gòu):
通過(guò)一個(gè) []byte 來(lái)反序列化得到這個(gè) Protocol ,一種思路是遍歷這個(gè) []byte ,然后逐一賦值。其實(shí)在 encoding/binary 包中有個(gè)方便的方法:
這個(gè)方法從一個(gè) io.Reader 中讀取字節(jié),并已 order 指定的端模式,來(lái)給填充 data (data需要是fixed-sized的結(jié)構(gòu)或者類(lèi)型)。要用到這個(gè)方法首先要有一個(gè) io.Reader ,從上面的圖中不難發(fā)現(xiàn),我們可以這么寫(xiě):
換句話(huà)說(shuō),我們將一個(gè) []byte 轉(zhuǎn)成了一個(gè) io.Reader 。
反過(guò)來(lái),我們需要將 Protocol 序列化得到 []byte ,使用 encoding/binary 包中有個(gè)對(duì)應(yīng)的 Write 方法:
通過(guò)將 []byte 轉(zhuǎn)成一個(gè) io.Writer 即可:
比如對(duì)于常見(jiàn)的基于文本行的 HTTP 協(xié)議的讀取,我們需要將一個(gè)流按照行來(lái)讀取。本質(zhì)上,我們需要一個(gè)基于緩沖的讀寫(xiě)機(jī)制(讀一些到緩沖,然后遍歷緩沖中我們關(guān)心的字節(jié)或字符)。在Go中有一個(gè) bufio 的包可以實(shí)現(xiàn)帶緩沖的讀寫(xiě):
這個(gè)ReadString方法從 io.Reader 中讀取字符串,直到 delim ,就返回 delim 和之前的字符串。如果將 delim 設(shè)置為 \n ,相當(dāng)于按行來(lái)讀取了:
等價(jià)于