91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Go語言中的字符串怎么拼接方法

發布時間:2021-10-21 09:04:14 來源:億速云 閱讀:150 作者:小新 欄目:開發技術

這篇文章主要介紹Go語言中的字符串怎么拼接方法,文中介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們一定要看完!

1、string類型

string類型的值可以拆分為一個包含多個字符(rune類型)的序列,也可以被拆分為一個包含多個字節 (byte類型) 的序列。其中一個rune類型值代表一個Unicode 字符,一個rune類型值占用四個字節,底層就是一個 UTF-8 編碼值,它其實是int32類型的一個別名類型。

package main

import (
 "fmt"
)

func main() {
 str := "你好world"
 fmt.Printf("The string: %q\n", str)
 fmt.Printf("runes(char): %q\n", []rune(str))
 fmt.Printf("runes(hex): %x\n", []rune(str))
 fmt.Printf("bytes(hex): [% x]\n", []byte(str))
}

執行結果:

The string: "你好world"
runes(char): ['你' '好' 'w' 'o' 'r' 'l' 'd']
runes(hex): [4f60 597d 77 6f 72 6c 64]
bytes(hex): e4 bd a0 e5 a5 bd 77 6f 72 6c 64

可以看到,英文字符使用一個字節,而中文字符需要三個字節。下面使用 for range 語句對上面的字符串進行遍歷:

for index, value := range str {
    fmt.Printf("%d: %q [% x]\n", index, value, []byte(string(value)))
}

執行結果如下:

0: '你' [e4 bd a0]
3: '好' [e5 a5 bd]
6: 'w' [77]
7: 'o' [6f]
8: 'r' [72]
9: 'l' [6c]
10: 'd' [64]

index索引值不是0-6,相鄰Unicode 字符的索引值不一定是連續的,因為中文字符占用了3個字節,寬度為3。

2、strings包

2.1 strings.Builder類型

strings.Builder的優勢主要體現在字符串拼接上,相比使用+拼接,效率更高。

  • strings.Builder已存在的值不可改變,只能重置(Reset()方法)或者拼接更多的內容。

  • 一旦調用了Builder值,就不能再以任何方式對其進行復制,比如函數間值傳遞、通道傳遞值、把值賦予變量等。

  • 在進行拼接時,Builder值會自動地對自身的內容容器進行擴容,也可以使用Grow方法進行手動擴容。

package main

import (
 "fmt"
 "strings"
)
func main() {
 var builder1 strings.Builder
 builder1.WriteString("hello")
 builder1.WriteByte(' ')
 builder1.WriteString("world")
 builder1.Write([]byte{' ', '!'})

 fmt.Println(builder1.String()) 

 f1 := func(b strings.Builder) {
  // b.WriteString("world !")  //會報錯
 }
 f1(builder1)

 builder1.Reset()
 fmt.Printf("The length 0f builder1: %d\n", builder1.Len())

}

執行結果:

hello world !
The length 0f builder1: 0

2.2 strings.Reader類型

strings.Reader類型可以用于高效地讀取字符串,它通過使用已讀計數機制來實現了高效讀取,已讀計數保存了已讀取的字節數,也代表了下一次讀取的起始索引位置。

package main

import (
 "fmt"
 "strings"
)
func main() { 
 reader1 := strings.NewReader("hello world!")
 buf1 := make([]byte, 6)
    fmt.Printf("reading index: %d\n", reader1.Size()-int64(reader1.Len()))
 
    reader1.Read(buf1)
 fmt.Println(string(buf1))
    fmt.Printf("reading index: %d\n", reader1.Size()-int64(reader1.Len()))
    
 reader1.Read(buf1)
 fmt.Println(string(buf1))
    fmt.Printf("reading index: %d\n", reader1.Size()-int64(reader1.Len()))
}

執行結果:

reading index: 0
hello
reading index: 6
world!
reading index: 12

可以看到,每讀取一次之后,已讀計數就會增加。

strings包的ReadAt方法不會依據已讀計數進行讀取,也不會更新已讀計數。它可以根據偏移量來自由地讀取Reader值中的內容。

package main

import (
 "fmt"
 "strings"
)
func main() {
    reader1 := strings.NewReader("hello world!")
    buf1 := make([]byte, 6)
 offset1 := int64(6)
 n, _ := reader1.ReadAt(buf1, offset1) 
 fmt.Println(string(buf2))
}

執行結果:

world!

也可以使用Seek方法來指定下一次讀取的起始索引位置。

package main

import (
 "fmt"
 "strings"
    "io"
)
func main() {
    reader1 := strings.NewReader("hello world!")
    buf1 := make([]byte, 6)
 offset1 := int64(6)
 readingIndex, _ := reader2.Seek(offset1, io.SeekCurrent)
 fmt.Printf("reading index: %d\n", readingIndex)

 reader1.Read(buf1)
 fmt.Printf("reading index: %d\n", reader1.Size()-int64(reader1.Len()))
 fmt.Println(string(buf1))
}

執行結果:

reading index: 6
reading index: 12
world!

3、bytes.Buffer

bytes包和strings包類似,strings包主要面向的是 Unicode 字符和經過 UTF-8 編碼的字符串,而bytes包面對的則主要是字節和字節切片,主要作為字節序列的緩沖區。bytes.Buffer數據的讀寫都使用到了已讀計數。

bytes.Buffer具有讀和寫功能,下面分別介紹他們的簡單使用方法。

3.1 bytes.Buffer:寫數據

strings.Builder一樣,bytes.Buffer可以用于拼接字符串,strings.Builder也會自動對內容容器進行擴容。請看下面的代碼:

package main

import (
 "bytes"
 "fmt"
)

func DemoBytes() {
 var buffer bytes.Buffer
 buffer.WriteString("hello ")
 buffer.WriteString("world !")
 fmt.Println(buffer.String())
}

執行結果:

hello world !

3.2 bytes.Buffer:讀數據

bytes.Buffer讀數據也使用了已讀計數,需要注意的是,進行讀取操作后,Len方法返回的是未讀內容的長度。下面直接來看代碼:

package main

import (
 "bytes"
 "fmt"
)

func DemoBytes() {
 var buffer bytes.Buffer
 buffer.WriteString("hello ")
 buffer.WriteString("world !")
    
    p1 := make([]byte, 5)
 n, _ := buffer.Read(p1)
    
 fmt.Println(string(p1))
 fmt.Println(buffer.String())
    fmt.Printf("The length of buffer: %d\n", buffer.Len())
}

執行結果:

hello
 world !
The length of buffer: 8

4、字符串拼接

簡單了解了string類型、strings包和bytes.Buffer類型后,下面來介紹golang中的字符串拼接方法。

https://zhuanlan.zhihu.com/p/349672248

go test -bench=. -run=^BenchmarkDemoBytes$

4.1 直接相加

最簡單的方法是直接相加,由于string類型的值是不可變的,進行字符串拼接時會生成新的字符串,將拼接的字符串依次拷貝到一個新的連續內存空間中。如果存在大量字符串拼接操作,使用這種方法非常消耗內存。

package main

import (
 "bytes"
 "fmt"
 "time"
)

func main() {
 str1 := "hello "
 str2 := "world !"
    str3 := str1 + str2
    fmt.Println(str3) 
}

4.2strings.Builder

前面介紹了strings.Builder可以用于拼接字符串:

var builder1 strings.Builder
builder1.WriteString("hello ")
builder1.WriteString("world !")

4.3 strings.Join()

也可以使用strings.Join方法,其實Join()調用了WriteString方法;

str1 := "hello "
str2 := "world !"
str3 := ""

str3 = strings.Join([]string{str3,str1},"")
str3 = strings.Join([]string{str3,str2},"")

4.4 bytes.Buffer

bytes.Buffer也可以用于拼接:

var buffer bytes.Buffer

buffer.WriteString("hello ")
buffer.WriteString("world !")

4.5 append方法

也可以使用Go內置函數append方法,用于拼接切片:

package main

import (
 "fmt"
)

func DemoAppend(n int) {
 str1 := "hello "
 str2 := "world !"
 var str3 []byte

    str3 = append(str3, []byte(str1)...)
    str3 = append(str3, []byte(str2)...)
 fmt.Println(string(str3))
}

執行結果:

hello world !

4.6 fmt.Sprintf

fmt包中的Sprintf方法也可以用來拼接字符串:

str1 := "hello "
str2 := "world !"
str3 := fmt.Sprintf("%s%s", str1, str2)

5、字符串拼接性能測試

下面來測試一下這6種方法的性能,編寫測試源碼文件strcat_test.go

package benchmark

import (
 "bytes"
 "fmt"
 "strings"
 "testing"
)

func DemoBytesBuffer(n int) {
 var buffer bytes.Buffer

 for i := 0; i < n; i++ {
  buffer.WriteString("hello ")
  buffer.WriteString("world !")
 }
}

func DemoWriteString(n int) {
 var builder1 strings.Builder
 for i := 0; i < n; i++ {
  builder1.WriteString("hello ")
  builder1.WriteString("world !")
 }
}

func DemoStringsJoin(n int) {
 str1 := "hello "
 str2 := "world !"
 str3 := ""
 for i := 0; i < n; i++ {
  str3 = strings.Join([]string{str3, str1}, "")
  str3 = strings.Join([]string{str3, str2}, "")
 }

}

func DemoPlus(n int) {

 str1 := "hello "
 str2 := "world !"
 str3 := ""
 for i := 0; i < n; i++ {
  str3 += str1
  str3 += str2
 }
}

func DemoAppend(n int) {

 str1 := "hello "
 str2 := "world !"
 var str3 []byte
 for i := 0; i < n; i++ {
  str3 = append(str3, []byte(str1)...)
  str3 = append(str3, []byte(str2)...)
 }
}

func DemoSprintf(n int) {
 str1 := "hello "
 str2 := "world !"
 str3 := ""
 for i := 0; i < n; i++ {
  str3 = fmt.Sprintf("%s%s", str3, str1)
  str3 = fmt.Sprintf("%s%s", str3, str2)
 }
}

func BenchmarkBytesBuffer(b *testing.B) {
 for i := 0; i < b.N; i++ {
  DemoBytesBuffer(10000)
 }
}

func BenchmarkWriteString(b *testing.B) {
 for i := 0; i < b.N; i++ {
  DemoWriteString(10000)
 }
}

func BenchmarkStringsJoin(b *testing.B) {
 for i := 0; i < b.N; i++ {
  DemoStringsJoin(10000)
 }
}

func BenchmarkAppend(b *testing.B) {
 for i := 0; i < b.N; i++ {
  DemoAppend(10000)
 }
}

func BenchmarkPlus(b *testing.B) {
 for i := 0; i < b.N; i++ {
  DemoPlus(10000)
 }
}

func BenchmarkSprintf(b *testing.B) {
 for i := 0; i < b.N; i++ {
  DemoSprintf(10000)
 }
}


執行性能測試:

$ go test -bench=. -run=^$
goos: windows
goarch: amd64
pkg: testGo/benchmark
cpu: Intel(R) Core(TM) i7-8550U CPU @ 1.80GHz
BenchmarkBytesBuffer-8              3436            326846 ns/op
BenchmarkWriteString-8              4148            271453 ns/op
BenchmarkStringsJoin-8                 3         402266267 ns/op
BenchmarkAppend-8                   1923            618489 ns/op
BenchmarkPlus-8                        3         345087467 ns/op
BenchmarkSprintf-8                     2         628330850 ns/op
PASS
ok      testGo/benchmark        9.279s

通過平均耗時可以看到WriteString方法執行效率最高。Sprintf方法效率最低。

  • 我們看到Strings.Join方法效率也比較低,在上面的場景下它的效率比較低,它在合并已有字符串數組的場合效率是很高的。

  • 如果要連續拼接大量字符串推薦使用WriteString方法,如果是少量字符串拼接,也可以直接使用+。

  • append方法的效率也是很高的,它主要用于切片的拼接。

  • fmt.Sprintf方法雖然效率低,但在少量數據拼接中,如果你想拼接其它數據類型,使用它可以完美的解決:

name := "zhangsan"
age := 20
str4 := fmt.Sprintf("%s is %d years old", name, age)
fmt.Println(str4)  // zhangsan is 20 years old

以上是“Go語言中的字符串怎么拼接方法”這篇文章的所有內容,感謝各位的閱讀!希望分享的內容對大家有幫助,更多相關知識,歡迎關注億速云行業資訊頻道!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

南投县| 三门县| 宜君县| 双流县| 将乐县| 六盘水市| 凤凰县| 乳山市| 呼图壁县| 宾阳县| 尚志市| 阳曲县| 永新县| 澎湖县| 乌兰浩特市| 沈丘县| 隆子县| 皮山县| 宝应县| 长寿区| 安顺市| 册亨县| 汨罗市| 上林县| 陕西省| 南溪县| 云浮市| 陆河县| 乐清市| 陵川县| 施甸县| 当阳市| 克拉玛依市| 五峰| 玉林市| 安泽县| 盐池县| 凭祥市| 香河县| 惠州市| 黔南|