广告
返回顶部
首页 > 资讯 > 后端开发 > GO >Go语言中的字符串拼接方法详情
  • 798
分享到

Go语言中的字符串拼接方法详情

2024-04-02 19:04:59 798人浏览 泡泡鱼
摘要

目录1、string类型2、strings包 2.1 strings.Builder类型2.2 strings.Reader类型3、bytes.Buffer3.1 bytes.Buf

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语言中的字符串拼接方法详情的文章就介绍到这了,更多相关Go语言中的字符串拼接方法内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

您可能感兴趣的文档:

--结束END--

本文标题: Go语言中的字符串拼接方法详情

本文链接: https://www.lsjlt.com/news/155002.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Go语言中的字符串拼接方法详情
    目录1、string类型2、strings包 2.1 strings.Builder类型2.2 strings.Reader类型3、bytes.Buffer3.1 bytes.Buf...
    99+
    2022-11-12
  • go语言字符串拼接的方法是什么
    在Go语言中,可以使用`+`运算符或`fmt.Sprintf()`函数来进行字符串拼接。1. 使用`+`运算符```gostr1 :...
    99+
    2023-09-27
    go语言
  • Go语言如何拼接字符串
    本篇内容主要讲解“Go语言如何拼接字符串”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Go语言如何拼接字符串”吧!拼接字符串的方法:1、使用“+”号拼接,语法“str = str1 + str2...
    99+
    2023-07-04
  • Go语言怎么拼接字符串
    拼接字符串的方法:1、使用“+”号拼接,语法“str = str1 + str2”;2、利用fmt包的sprintf()函数拼接,语法“str = fmt.Sprintf("%s%d%s", s1, i, s2)”;3、...
    99+
    2023-05-14
    拼接字符串 go语言 Golang
  • go语言中字符串的拼接方式有哪些
    本篇内容主要讲解“go语言中字符串的拼接方式有哪些”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“go语言中字符串的拼接方式有哪些”吧!+拼接方式这种方式是我在写golang经常用的方式,go语言...
    99+
    2023-06-22
  • go语言中五种字符串的拼接方式(小结)
    目录+拼接方式sprintf函数Join函数buffer.Builderbuffer.WriteString函数buffer.Builder函数ps:直接使用运算符主要结论+拼...
    99+
    2022-06-07
    小结 GO 字符串 go语言 字符
  • Golang语言如何高效拼接字符串详解
    目录01、介绍02、操作符 +03、strings.Join 方法04、fmt.Sprint 方法05、bytes.Buffer 类型06、strings.Builder 类型07、...
    99+
    2022-11-12
  • R语言拼接字符串_paste的用法说明
    R中自带的字符串连接的函数是paste。 先来看一下官方文档里对paste用法的解释: 基本格式: paste (…, sep = " ", collapse = NULL) ...
    99+
    2022-11-12
  • go语言删除字符串字符的方法介绍
    今天小编给大家分享的是go语言删除字符串字符的方法介绍,相信很多人都不太了解,为了让大家更加了解,所以给大家总结了以下内容,一起往下看吧。一定会有所收获的哦。   删除字符串的方法:1、用TrimSpace()...
    99+
    2023-07-04
  • 使用Go语言文档中的strings.Join函数实现字符串拼接
    使用Go语言实现字符串拼接,是日常编程工作中非常常见的需求。其中,Go语言内置的strings.Join函数可以帮助我们轻松地实现字符串拼接。本文将介绍如何使用Go语言文档中的strings.Join函数实现字符串拼接,并提供具体的代码示例...
    99+
    2023-11-04
    Go语言 字符串拼接 stringsJoin函数
  • GoLang中拼接字符串性能优化方法详解
    字符串在内存中是不可变的,放在只读内存段,因此你可以使用str[0]来访问,但是不能使用str[0]='a'来修改。 修改字符串实际上是重新放入新的地址,因此拼接字符...
    99+
    2023-02-03
    GoLang拼接字符串 GoLang拼接字符串性能优化
  • python3 拼接字符串的7种方法
    1、直接通过(+)操作符拼接 >>> 'Hello' + ' ' + 'World' + '!' 'Hello World!' 使用这种方式进行字符串连接的操作效率低下,因为python中使用 + 拼接两个字符串时会...
    99+
    2023-01-30
    种方法 字符串
  • java中拼接字符串有哪些方法
    这篇文章给大家分享的是有关java中拼接字符串有哪些方法的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。示例代码public class Test {  List&...
    99+
    2023-05-30
  • Python中的字符串拼接方法有哪些?
    Python中的字符串拼接方法有很多,本文将介绍几种常用的方法,并提供相应的代码示例。这些方法包括使用"+"符号、使用join()方法、使用format()方法以及使用f-string。使用"+"符号拼接字符串:这是一种最简单直接的方法,只...
    99+
    2023-10-22
    字符串拼接方法: 使用指定的分隔符。
  • es6中拼接字符串的方法有哪些
    这篇“es6中拼接字符串的方法有哪些”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“es6中...
    99+
    2022-10-19
  • python中有哪些拼接字符串的方法
    python中拼接字符串的方法有:1.直接连接;2.使用加号连接;3.使用逗号连接;4.使用%连接;5.使用format连接;6.使用f-string方式连接;7.使用join方法连接;python中拼接字符串的方法有以下几种直接连接字符串...
    99+
    2022-10-14
  • python中字符串的拼接方法有哪些
    在Python中,字符串的拼接可以使用以下几种方法:1. 使用"+"运算符进行拼接:```pythonstr1 = "Hello"s...
    99+
    2023-08-18
    python
  • 怎么在R语言中对字符串进行拼接
    这篇文章将为大家详细讲解有关怎么在R语言中对字符串进行拼接,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。在R语言中 paste 是一个很有用的字符串处理函数,可以连接不同类型的变量及常量。函...
    99+
    2023-06-14
  • R语言中字符串的拼接操作实例讲解
    在R语言中 paste 是一个很有用的字符串处理函数,可以连接不同类型的变量及常量。 函数paste的一般使用格式为: paste(..., sep = " ", collaps...
    99+
    2022-11-11
  • python字符串拼接的方法有哪些
    这篇文章主要介绍python字符串拼接的方法有哪些,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!python有哪些常用库python常用的库:1.requesuts;2.scrapy;3.pillow;4.twist...
    99+
    2023-06-14
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作