欧美一区二区三区老妇人-欧美做爰猛烈大尺度电-99久久夜色精品国产亚洲a-亚洲福利视频一区二区

go語言byte類型 golang byte類型

Golang bytes.buffer詳解

Buffer 介紹

成都創(chuàng)新互聯(lián)公司專注于石景山網(wǎng)站建設(shè)服務(wù)及定制,我們擁有豐富的企業(yè)做網(wǎng)站經(jīng)驗(yàn)。 熱誠為您提供石景山營銷型網(wǎng)站建設(shè),石景山網(wǎng)站制作、石景山網(wǎng)頁設(shè)計(jì)、石景山網(wǎng)站官網(wǎng)定制、微信平臺(tái)小程序開發(fā)服務(wù),打造石景山網(wǎng)絡(luò)公司原創(chuàng)品牌,更為您提供石景山網(wǎng)站排名全網(wǎng)營銷落地服務(wù)。

Buffer 是 bytes 包中的一個(gè) type Buffer struct{…}

A buffer is a variable-sized buffer of bytes with Read and Write methods. The zero value for Buffer is an empty buffer ready to use.

(是一個(gè)變長的 buffer,具有 Read 和Write 方法。 Buffer 的 零值 是一個(gè) 空的 buffer,但是可以使用)

Buffer 就像一個(gè)集裝箱容器,可以存東西,取東西(存取數(shù)據(jù))

創(chuàng)建緩沖器

輸出

寫入到緩沖器

buffer在new的時(shí)候是空的,也是可以直接Write的

Write

結(jié)果

WriteString

結(jié)果

WriteByte

WriteRune

結(jié)果

從緩沖器中寫出

讀出緩沖器

Read

ReadByte

返回緩沖器頭部的第一個(gè)byte

ReadRun

ReadRune方法,返回緩沖器頭部的第一個(gè)rune

為什么n==3,而n1==1呢?我們看下ReadRune 的源碼

ReadBytes

ReadBytes方法,需要一個(gè)byte作為分隔符,讀的時(shí)候從緩沖器里找出第一個(gè)出現(xiàn)的分隔符,緩沖器頭部開始到分隔符之間的byte返回。

相當(dāng)于有一個(gè)分隔符

ReadString

和readBytes方法類似

讀入緩沖器

ReadFrom方法,從一個(gè)實(shí)現(xiàn)io.Reader接口的r,把r的內(nèi)容讀到緩沖器里,n返回讀的數(shù)量

從緩沖器取出

Next方法,返回前n個(gè)byte(slice),原緩沖器變

緩沖區(qū)原理介紹

go字節(jié)緩沖區(qū)底層以字節(jié)切片做存儲(chǔ),切片存在長度len與容量cap, 緩沖區(qū)寫從長度len的位置開始寫,當(dāng)lencap時(shí),會(huì)自動(dòng)擴(kuò)容。緩沖區(qū)讀會(huì)從內(nèi)置標(biāo)記off位置開始讀(off始終記錄讀的起始位置),當(dāng)off==len時(shí),表明緩沖區(qū)已全部讀完

并重置緩沖區(qū)(len=off=0),此外當(dāng)將要內(nèi)容長度+已寫的長度(即len) = cap/2時(shí),緩沖區(qū)前移覆蓋掉已讀的內(nèi)容(off=0,len-=off),從避免緩沖區(qū)不斷擴(kuò)容

數(shù)據(jù)段保存有如下字符串:string byte

string是Go語言中的基礎(chǔ)數(shù)據(jù)類型。

聲明string變量非常簡單,常見的方式有以下兩種:

聲明一個(gè)空字符串后再賦值。

var s string。

s = "hello world"。

需要注意的是空字符只是長度為0,但不是nil。不存在值為nil的string。

使用簡短變量聲明:

s := "hello world" //直接初始化字符串。

雙引號(hào)與單引號(hào)。

字符串不僅可以使用雙引號(hào)賦值,也可以使用反單引號(hào)賦值,它們的區(qū)別是在于對特殊字符的處理。

假如我們希望string變量表示下面的字符串,它包括換行符和雙引號(hào):

Hi。

this is "Steven"。

1。

2。

使用雙引號(hào)表示時(shí),需要對特殊字符轉(zhuǎn)義,如下所示:

s:= "Hi, \nthis is \"Steven\"."。

1。

如果使用反單引號(hào)時(shí),不需要對特殊符號(hào)轉(zhuǎn)義,如下所示:

s := Hi。

this is "Steven"。

需要注意的是,字符串拼接會(huì)觸發(fā)內(nèi)存分配以及內(nèi)存拷貝,單行語句拼接多個(gè)字符串只分配一次內(nèi)存。比如上面的語句中,在拼接時(shí),會(huì)先計(jì)算最終字符串的長度后再分配內(nèi)存。

類型轉(zhuǎn)換:

項(xiàng)目中,數(shù)據(jù)經(jīng)常需要在string和字節(jié)[]byte之間轉(zhuǎn)換。

Go語言中的字節(jié)序

Go中的binary包實(shí)現(xiàn)了簡單的數(shù)字與字節(jié)序列的轉(zhuǎn)換以及變長值的編解碼

package main

import ( "fmt" "bytes" "encoding/binary" ) func main(){ n := 0x12345678 bytesBuffer := bytes.NewBuffer([]byte{}) //BigEndian 大端順序存儲(chǔ) LittleEndian小端順序存儲(chǔ) binary.Write(bytesBuffer, binary.BigEndian, int32(n)) data:=bytesBuffer.Bytes() fmt.Printf("[0]: %#x addr:%#x\n",data[0],data[0]) fmt.Printf("[0]: %#x addr:%#x\n",data[1],data[1]) fmt.Printf("[0]: %#x addr:%#x\n",data[2],data[2]) fmt.Printf("[0]: %#x addr:%#x\n",data[3],data[3]) }

輸出

[0]: 0x12 addr:0xc042010248 [1]: 0x34 addr:0xc042010249 [2]: 0x56 addr:0xc04201024a [3]: 0x78 addr:0xc04201024b

也可以使用下面的方式

n := 0x12345678 var data []byte = make([]byte,4) //操作的都是無符號(hào)整型 binary.BigEndian.PutUint32(data,uint32(n))

可以使用下面的方式判斷當(dāng)前系統(tǒng)的字節(jié)序類型

const INT_SIZE int = int(unsafe.Sizeof(0))

//判斷我們系統(tǒng)中的字節(jié)序類型 func systemEdian() { var i int = 0x1 bs := (*[INT_SIZE]byte)(unsafe.Pointer(i)) if bs[0] == 0 { fmt.Println("system edian is little endian") } else { fmt.Println("system edian is big endian") } }

請Golang深度用戶說說,現(xiàn)在Golang的性能可以和C比嗎

不可以,完全沒有可比性。

Golang的優(yōu)勢是開發(fā)速度,C可以自由、精準(zhǔn)的操控內(nèi)存。

拿string類型舉個(gè)栗子:

1、修改字符串:

golang:需要分配新內(nèi)存,然后進(jìn)行內(nèi)存copy。

c:可直接修改,可realloc。

2、存一段data:

golang:使用[]byte類型,[]byte轉(zhuǎn)成string需要進(jìn)行內(nèi)存拷貝(排除掉利用指針進(jìn)行類型轉(zhuǎn)換的情況)。

c:直接用char[],可讀可寫。

golang中為了語言的安全性,類似的這種限制有很多,犧牲了一部分性能。但golang的優(yōu)勢也是顯而易見的,goroutine、chan都很好用,而c則需要自己進(jìn)行進(jìn)程、線程的管控。

Golang的數(shù)據(jù)類型

1.按長度:int8(-128-127)、int16、int32、int64

2.無符號(hào)整型:uint8(0-255)、uint16、uint32、uint64

int:? 32位操作系統(tǒng)上就是int32,64位操作系統(tǒng)上就是int64

uint:?32位操作系統(tǒng)上就是uint32,64位操作系統(tǒng)上就是uint64

float32? ? ? float64

complex64和complex128

bool

string

byte? 和? rune

go語言string之Buffer與Builder

操作字符串離不開字符串的拼接,但是Go中string是只讀類型,大量字符串的拼接會(huì)造成性能問題。

拼接字符串,無外乎四種方式,采用“+”,“fmt.Sprintf()”,"bytes.Buffer","strings.Builder"

上面我們創(chuàng)建10萬字符串拼接的測試,可以發(fā)現(xiàn)"bytes.Buffer","strings.Builder"的性能最好,約是“+”的1000倍級(jí)別。

這是由于string是不可修改的,所以在使用“+”進(jìn)行拼接字符串,每次都會(huì)產(chǎn)生申請空間,拼接,復(fù)制等操作,數(shù)據(jù)量大的情況下非常消耗資源和性能。而采用Buffer等方式,都是預(yù)先計(jì)算拼接字符串?dāng)?shù)組的總長度(如果可以知道長度),申請空間,底層是slice數(shù)組,可以以append的形式向后進(jìn)行追加。最后在轉(zhuǎn)換為字符串。這申請了不斷申請空間的操作,也減少了空間的使用和拷貝的次數(shù),自然性能也高不少。

bytes.buffer是一個(gè)緩沖byte類型的緩沖器存放著都是byte

是一個(gè)變長的 buffer,具有 Read 和Write 方法。 Buffer 的 零值 是一個(gè) 空的 buffer,但是可以使用,底層就是一個(gè) []byte, 字節(jié)切片。

向Buffer中寫數(shù)據(jù),可以看出Buffer中有個(gè)Grow函數(shù)用于對切片進(jìn)行擴(kuò)容。

從Buffer中讀取數(shù)據(jù)

strings.Builder的方法和bytes.Buffer的方法的命名幾乎一致。

但實(shí)現(xiàn)并不一致,Builder的Write方法直接將字符拼接slice數(shù)組后。

其沒有提供read方法,但提供了strings.Reader方式

Reader 結(jié)構(gòu):

Buffer:

Builder:

可以看出Buffer和Builder底層都是采用[]byte數(shù)組進(jìn)行裝載數(shù)據(jù)。

先來說說Buffer:

創(chuàng)建好Buffer是一個(gè)empty的,off 用于指向讀寫的尾部。

在寫的時(shí)候,先判斷當(dāng)前寫入字符串長度是否大于Buffer的容量,如果大于就調(diào)用grow進(jìn)行擴(kuò)容,擴(kuò)容申請的長度為當(dāng)前寫入字符串的長度。如果當(dāng)前寫入字符串長度小于最小字節(jié)長度64,直接創(chuàng)建64長度的[]byte數(shù)組。如果申請的長度小于二分之一總?cè)萘繙p去當(dāng)前字符總長度,說明存在很大一部分被使用但已讀,可以將未讀的數(shù)據(jù)滑動(dòng)到數(shù)組頭。如果容量不足,擴(kuò)展2*c + n 。

其String()方法就是將字節(jié)數(shù)組強(qiáng)轉(zhuǎn)為string

Builder是如何實(shí)現(xiàn)的。

Builder采用append的方式向字節(jié)數(shù)組后添加字符串。

從上面可以看出,[]byte的內(nèi)存大小也是以倍數(shù)進(jìn)行申請的,初始大小為 0,第一次為大于當(dāng)前申請的最大 2 的指數(shù),不夠進(jìn)行翻倍.

可以看出如果舊容量小于1024進(jìn)行翻倍,否則擴(kuò)展四分之一。(2048 byte 后,申請策略的調(diào)整)。

其次String()方法與Buffer的string方法也有明顯區(qū)別。Buffer的string是一種強(qiáng)轉(zhuǎn),我們知道在強(qiáng)轉(zhuǎn)的時(shí)候是需要進(jìn)行申請空間,并拷貝的。而Builder只是指針的轉(zhuǎn)換。

這里我們解析一下 *(*string)(unsafe.Pointer(b.buf)) 這個(gè)語句的意思。

先來了解下unsafe.Pointer 的用法。

也就是說,unsafe.Pointer 可以轉(zhuǎn)換為任意類型,那么意味著,通過unsafe.Pointer媒介,程序繞過類型系統(tǒng),進(jìn)行地址轉(zhuǎn)換而不是拷貝。

即*A = Pointer = *B

就像上面例子一樣,將字節(jié)數(shù)組轉(zhuǎn)為unsafe.Pointer類型,再轉(zhuǎn)為string類型,s和b中內(nèi)容一樣,修改b,s也變了,說明b和s是同一個(gè)地址。但是對s重新賦值后,意味著s的地址指向了“WORLD”,它們所使用的內(nèi)存空間不同了,所以s改變后,b并不會(huì)改變。

所以他們的區(qū)別就在于 bytes.Buffer 是重新申請了一塊空間,存放生成的string變量, 而strings.Builder直接將底層的[]byte轉(zhuǎn)換成了string類型返回了回來,去掉了申請空間的操作。

本文題目:go語言byte類型 golang byte類型
瀏覽路徑:http://chinadenli.net/article36/hgpepg.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站營銷營銷型網(wǎng)站建設(shè)企業(yè)建站App設(shè)計(jì)靜態(tài)網(wǎng)站網(wǎng)站內(nèi)鏈

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

網(wǎng)站優(yōu)化排名