String stitching method
use+
Number
use+
The method of splicing strings is to create a new string every time you splice it, and then copy the original string into the new string, which will lead to a large amount of memory allocation and copying operations, with poor performance.
String formatting functionfunction
Pre-allocatedBuffer
func BufferCapResize() { var str = "abcd" var buf // Preallocate memory (4 * 10000) // If there is no such line, the capacity will be expanded when the length is not enough cap := 0 for i := 0; i < 10000; i++ { if () != cap { println("cap:", ()) cap = () } (str) } }
- Pre-allocated
Builder
- Pre-allocated
[]byte
- use
function
and
The bottom layer is a byte array, but
When converting strings, you need to reapply the memory space, and
It directly puts the bottom layer
bytes
Convert to a string to return
-
string([:])
Directly force -
((), len())
Zero copy conversion
String memory leak
Point to the same memory space when intercepting characters
How to avoid:
- Convert substrings into byte slices, converting them into
string
- After intercepting, splicing a new string in front
- use
Reconstruct new strings
Define a long strings := ("a", 1<<20)
,
Assignment
①
②
④
Printed at the same address③
Printed onenil
The string will not be copied when assigning, but only changes the underlying pointer pointer.
Original strings
Even if it is reassigned to an empty string,s2
Still pointing to the original string, so the original address will not be released
func main() { ptr := (*)((&s)) ("s pointer:", ()) // ① 0xc000180000 Assign() } func Assign() { s2 := s ptr := (*)((&s2)) ("Assign:", ()) // ② 0xc000180000 s := "" ptr = (*)((&s)) ("s pointer", ()) // ③ nil ptr = (*)((&s2)) ("Assign", ()) // ④ 0xc000180000 _ = s2 }
Assign by reference
Whether it is assigned through reference or value assignment, it ultimately points to the same address
func main() { ptr := (*)((&s)) ("s pointer:", ()) // ① 0xc000180000 AssignPointer() } func AssignPointer() { s2 := &s // Assign values by reference ptr := (*)((s2)) ("AssignPointer:", ()) // ② 0xc000180000 _ = s2 }
String intercept
s2
It's intercepteds
Before the string20
Sos2
ands
The starting address is the same
This solution can easily lead to memory leaks because stringss
There is a lot of room for application.s
It will not be recycled without use, becauses2
Pointed tos
Address
func main() { ptr := (*)((&s)) ("s pointer:", ()) // ① 0xc000100000 StringSlice() } func StringSlice() { s2 := s[:20] ptr := (*)((&s2)) ("StringSlice:", ()) // ② 0xc000100000 _ = s2 }
String pass
The string is passed inside the function. Whether it is a pointer or a value, the address of the actual content of the string in memory is the same.
func main() { ptr := (*)((&s)) ("s pointer:", ()) // ① 0x49b7ba f1(s) f2(&s) } func f1(s string) string { ptr := (s) ("f1:", ptr) // ② 0x49b7ba return s } func f2(s *string) *string { ptr := (*s) ("f2:", ptr) // ③ 0x49b7ba return s }
You may find that it is said that the Internet will not copy when passing pointers, and the copy will occur when passing values, but why is the string not copying now, whether it is passing pointers or passing values, no copying occurs when passing strings.
This is because&s
The function parameters are printeds
The address on the stack will be different every time the function call is called
func main() { ptr := (*)((&s)) ("s pointer:", ()) // ① 0x49b7ba ("s Address:", &s) // 0x528650 f1(s) f2(&s) } func f1(s string) string { ("f1 s:", &s) // 0xc000014070 ptr := (s) ("f1:", ptr) // 0x49b7ba return s } func f2(s *string) *string { ("f2 s:", s) // 0x528650 ptr := (*s) ("f2:", ptr) // 0x49b7ba return s }
How to change the string address
1. Forced
func StringSlice1(s string) string { ("string:", (s)) // 0xc000100000 s1 := string([]byte(s[:20])) ptr := (s1) ("StringSlice1:", ptr) // 0xc0000bc000 return s1 }
2. Change the first character and you can change its1
Address
func StringSlice2(s string) string { ("string:", (s)) // 0xc000100000 s1 := (" " + s[:20])[1:] ptr := (s1) ("StringSlice2:", ptr) // 0xc000018199 return s1 }
3. UseStringsBuilder
Changes1
Address
func StringSliceUseBuilder(s string) string { ("string:", (s)) // 0xc000100000 var b (20) (s[:20]) s1 := () ptr := (s1) ("StringSliceUseBuilder:", ptr) // 0xc0000b0000 return s1 }
Character switching zero copy conversion
Although both are slice operations,s1
will change the address, ands2
Will not change the address
-
s1
Pointer type that is forced to string -
s2
: Right firsts
Do a finger fetch, convert it into a string slice pointer type, and then get the content of the pointer
sos2
The method is zero copy conversion
func main() { ptr := (*)((&s)) ("s pointer:", ()) // 0xc000180000 } func stringToBytes() { s1 := []byte(s) ("s1: ", (s1)) // 0xc000280000 s2 := *(*[]byte)((&s)) ("s2: ", (s2)) // 0xc000180000 }
This is the article about the problems and solutions in string assignment in Go. For more related contents of Go string assignment, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!