Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to concatenate strings in Go language

2025-01-17 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/03 Report--

This article mainly introduces how to concatenate strings in Go language, which is very detailed and has certain reference value. Friends who are interested must finish it!

1. String type

Values of type string can be split into a sequence containing multiple characters (rune type) or into a sequence containing multiple bytes (byte type). One of the rune type values represents a Unicode character, a rune type value takes up four bytes, and the underlying value is a UTF-8-encoded value, which is actually an alias type of the int32 type.

Package mainimport ("fmt") func main () {str: = "Hello 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))}

Execution result:

The string: "Hello, world"

Runes (char): ['you', 'good','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

As you can see, English characters use one byte, while Chinese characters need three bytes. The following uses the for range statement to traverse the above string:

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

The implementation results are as follows:

'you' [e4 bd a0]

'good 'e5a5 bd.

'w' 77.

'o' 6f

'r'[72]

'l'6c

'd' [64]

The index index value is not 0-6, and the index values of adjacent Unicode characters are not necessarily contiguous, because Chinese characters occupy 3 bytes and have a width of 3.

2. Strings package

2.1 strings.Builder Typ

The advantage of strings.Builder is mainly reflected in string concatenation, which is more efficient than using + splicing.

The existing value of strings.Builder cannot be changed, but can only be reset (Reset () method) or concatenate more content.

Once the Builder value is called, it can no longer be copied in any way, such as passing values between functions, passing values in channels, assigning values to variables, and so on.

When stitching, the Builder value will automatically expand its content container, or you can use the Grow method to expand the capacity manually.

Package mainimport ("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!") / will report an error} F1 (builder1) builder1.Reset () fmt.Printf ("The length 0f builder1:% d\ n", builder1.Len ())}

Execution result:

Hello world!

The length 0f builder1: 0

2.2 strings.Reader Typ

The strings.Reader type can be used to read strings efficiently, and it achieves efficient reading by using the read count mechanism, which holds the number of bytes read and represents the starting index position of the next read.

Package mainimport ("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 ())}

Execution result:

Reading index: 0

Hello

Reading index: 6

World!

Reading index: 12

As you can see, after each read, the read count increases.

The ReadAt method of the strings package does not read based on the read count, nor does it update the read count. It can freely read the contents of the reader value according to the offset.

Package mainimport ("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))}

Execution result:

World!

You can also use the Seek method to specify the starting index location for the next read.

Package mainimport ("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))}

Execution result:

Reading index: 6

Reading index: 12

World!

3 、 bytes.Buffer

Bytes package is similar to strings package, strings package is mainly aimed at Unicode characters and UTF-8-encoded strings, while bytes package is mainly faced with bytes and byte slices, mainly as a buffer for byte sequences. Read counts are used to read and write bytes.Buffer data.

Bytes.Buffer has read and write functions. Here are some simple ways to use them.

3.1 bytes.Buffer: write data

Like strings.Builder, bytes.Buffer can be used to concatenate strings, and strings.Builder automatically expands the content container. Take a look at the following code:

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

Execution result:

Hello world!

3.2 bytes.Buffer: read data

The bytes.Buffer read data also uses a read count, and it is important to note that after the read operation, the Len method returns the length of the unread content. Let's take a look at the code directly:

Package mainimport ("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 ())}

Execution result:

Hello

World!

The length of buffer: 8

4. String concatenation

After a brief understanding of the string type, the string package, and the bytes.Buffer type, let's introduce the string concatenation method in golang.

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

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

4.1 Direct addition

The easiest way is to add directly, because the value of the string type is immutable, a new string is generated when the string is concatenated, and the concatenated strings are copied into a new contiguous memory space in turn. If there are a large number of string concatenation operations, using this method is very memory-intensive.

Package mainimport ("bytes"fmt"time") func main () {str1: = "hello" str2: = "world!" Str3: = str1 + str2 fmt.Println (str3)} 4.2strings.Builder

I introduced earlier that strings.Builder can be used to concatenate strings:

Var builder1 strings.Builderbuilder1.WriteString ("hello") builder1.WriteString ("world!") 4.3 strings.Join ()

You can also use the strings.Join method, but Join () calls the WriteString method

Str1: = "hello" str2: = "world!" str3: = "" str3 = strings.Join ([] string {str3,str1}, "") str3 = strings.Join ([] string {str3,str2}, ") 4.4 bytes.Buffer

Bytes.Buffer can also be used for stitching:

Var buffer bytes.Bufferbuffer.WriteString ("hello") buffer.WriteString ("world!") 4.5 append method

You can also use the Go built-in function append method to splice slices:

Package mainimport ("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))}

Execution result:

Hello world!

4.6 fmt.Sprintf

The Sprintf method in the fmt package can also be used to concatenate strings:

Str1: = "hello" str2: = "world!" str3: = fmt.Sprintf ("% s% s", str1, str2) 5. String splicing performance test

Let's test the performance of these six methods and write the test source file strcat_test.go:

Package benchmarkimport ("bytes"fmt"strings"testing") func DemoBytesBuffer (n int) {var buffer bytes.Buffer for I: = 0; I < n; iSum + {buffer.WriteString ("hello") buffer.WriteString ("world!")} func DemoWriteString (n int) {var builder1 strings.Builder for I: = 0; I < n ITunes + {builder1.WriteString ("hello") builder1.WriteString ("world!")} func DemoStringsJoin (n int) {str1: = "hello" str2: = "world!" Str3: = "for I: = 0; I < n; iTunes + {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; iTunes + {str3 + = str1 str3 + = str2}} func DemoAppend (n int) {str1: = "hello" str2: = "world!" Var str3 [] byte for i: = 0; I < n; iTunes + {str3 = append (str3, [] byte (str1)...) Str3 = append (str3, [] byte (str2)...)} func DemoSprintf (n int) {str1: = "hello" str2: = "world!" Str3: = "" for I: = 0; I < n; iTunes + {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; iTunes + {DemoBytesBuffer (10000)}} func BenchmarkWriteString (b * testing.B) {for I: = 0; I < b.N IThis + {DemoWriteString (10000)}} func BenchmarkStringsJoin (b * testing.B) {for I: = 0; I < b.N; iBN + {DemoStringsJoin (10000)}} func BenchmarkAppend (b * testing.B) {for I: = 0; I < b.N; iBN + {DemoAppend (10000)}} func BenchmarkPlus (b * testing.B) {for I: = 0; I < b.N; iBN + {DemoPlus (10000)}} func BenchmarkSprintf (b * testing.B) {for I: = 0. ITunes + {DemoSprintf (10000)}} perform performance test: $go test-bench=. -run= ^ $goos: windowsgoarch: amd64pkg: testGo/benchmarkcpu: Intel (R) Core (TM) i7-8550U CPU @ 1.80GHzBenchmarkBytesBuffer-8 3436 326846 ns/opBenchmarkWriteString-8 4148 271453 ns/opBenchmarkStringsJoin-8 3 402266267 ns/opBenchmarkAppend-8 1923 618489 ns/opBenchmarkPlus-8 3 345087467 ns/opBenchmarkSprintf-8 2 628330850 ns/opPASSok testGo/benchmark 9.279s

From the average time spent, you can see that the WriteString method is the most efficient. The Sprintf method is the least efficient.

We can see that the Strings.Join method is also relatively inefficient. In the above scenario, it is relatively inefficient, and it is very efficient in merging existing string arrays.

It is recommended to use the WriteString method if you want to concatenate a large number of strings continuously, or you can use + directly if it is a small amount of string concatenation.

The efficiency of append method is also very high, it is mainly used for slice splicing.

Fmt.Sprintf method is inefficient, but in a small amount of data stitching, if you want to splice other data types, you can use it to solve the problem perfectly:

Name: = "zhangsan" age: = 20str4: = fmt.Sprintf ("% s is% d years old", name, age) fmt.Println (str4) / / zhangsan is 20 years old is all the contents of the article "how to concatenate strings in Go language". Thank you for reading! Hope to share the content to help you, more related knowledge, welcome to follow the industry information channel!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report