当前位置:网站首页>Go language, array, string, slice
Go language, array, string, slice
2022-04-23 16:54:00 【The interview was rejected 10000 times】
Array , character string , section
Notes It's a personal summary 《Go Language advanced programming 》 Learning notes of
Basic data structure , Only when these are not satisfied will the linked list be used ,map, Structure and other data structures .
Array , character string , section Have the same memory structure , Are contiguous blocks of memory , Because of the limitation in grammar, there are different expressions , Understand the memory structure , They can be better understood and used
- Array : Corresponding continuous byte array , Memory data can be modified , But it's a value type , Both assignment and parameter transfer are global assignment
- character string : Corresponding continuous byte array , Memory data cannot be modified , Read-only property
- section : Most used , An array of contiguous bytes , But the slice head contains Pointer to underlying data , Data length and capacity information , When passing parameters, you only need to pass this information , More efficient
Array
Memory block of data type of continuous memory , Follow c The difference in language is ,Go The array name in is a value type ,
- stay c In language , The array name table shows the address of the first element of the array , In other words, array names have the concept of addresses
int a[10],*p;
p = a;
p = &a[0]; // When passing parameters , Just pass the first address
- stay go in , The array name represents an array variable , Not the address that points to the first element of the array , When assigning or transferring parameters , The whole array is passed , Not enough efficient
a := [...]int {
1,2,3} // Declare and initialize a = {1,2,3}
func test(a [3]int){
...
}
test(a) // Passing is the entire array
Arrays can define a variety of array types , It looks fun
- A character array
var s1=[2]string{
"hello", "world"}
- Array of structs
var line2 = [...]People.Student{
People.Student{
age : 30 , score :100}, People.Student{
age : 20 , score :100}}
- Function array
var decoder2 = [...] func (io.Reader) (image.Image, error){
png.Decode,
jpeg.Decode,
}
- Interface array
var unknown2 = [...] interface {
}{
123 , " Hello " }
- Pipeline array
var chanList = [2] chan int{
}
character string
The string is It can't be changed Character sequence ,Go The definition of string in language is a structure
type StringHeader struct {
Data uintptr
Len int
}
Personal understanding : Open up a structure memory on the stack ,Data Character constant pointing to static area ,Len Represents character length , That is, the underlying structure of each string is also a structure , The book also says that character arrays are also structural arrays in essence
Confusion remains unsolved :
func testString() {
string1 := [...]string{
"helloooooooo", "worlddddddd"}
fmt.Printf("arr = %p, string1[0] =%p,string1[0] =%s,len string1[0] = %d,string[1] = %p", &string1, &string1[0], string1[0], len(string1[0]), &string1[1])
//arr = 0xc000062040, string1[0] =0xc000062040,string1[0] =helloooooooo,len string1[0] = 12,string[1] = 0xc000062050
}
// string1[0] Is the length of the 12,
// &string1[1] - &string[0] = 10 Why is that? , I think the result will be &string1[1] - &string[0] = 13
section
Structure definition of slice
type SliceHeader struct {
Data uintptr
Len int
Cap int
}
Slicing is a simple dynamic array , One more than the string cap Capacity , The idea of dynamic arrays is , As long as the length is less than the capacity , When you add elements , Memory will not be reallocated if it is not larger than the capacity , Can't copy data , Exceeding the capacity will reallocate memory space , Then slice and copy . When assigning and passing parameters , Are the assignment and parameter transfer of the structure
Slice definition
var a = []int // nil section a == nil
var b = []int {
} // Empty set , It's not equal to nil
var c = []int {
1,2,3} //len = 3 ,cap = 3
var d = make([]int ,2,3) //len = 2 , cap = 3
The difference between arrays
- The same thing
Built in len Function returns the length of the valid element in the slice , Built in cap Function returns the slice size , The traversal and computation lengths are the same
- Difference
- The slice capacity is greater than or equal to the length , Array must be equal to .
- What has a length definition is an array , Nothing is slicing .
- Arrays are value types , Assignment is an overall assignment , A slice is a structure , The type and length of the array should be the same as the data type , The type of slice is independent of the length , As long as the slices composed of the same data type are all slices of the same type ,
Addition and deletion of slices
First, let's look at the calculation of the length and capacity of the slice in the assignment
func SliceAssignment() {
// First, let's review What is the opening and closing interval
// a,b All real numbers between , But does not include a,b Remember to do (a,b)
// a,b All real numbers between , Include a,b And a < b Remember to do [a,b]
// Opening and closing rules of slices
a := []int{
10, 20, 30, 40, 50, 60, 7, 8, 9}
fmt.Printf(" len: %d, cap: %d , arr = %p , arr %+v \n", len(a), cap(a), a, a)
//len: 9, cap: 9 , arr = 0xc0000ba000 , arr [10 20 30 40 50 60 7 8 9]
d := a[:3] // Left closed right away [0,3)
fmt.Printf(" len: %d, cap: %d , arr = %p , arr %+v \n", len(d), cap(d), d, d)
//len: 3, cap: 9 , arr = 0xc0000ba000 , arr [10 20 30]
b := a[2:]
fmt.Printf(" len: %d, cap: %d , arr = %p , arr %+v \n", len(b), cap(b), b, b)
// len: 7, cap: 7 , arr = 0xc0000ba010 , arr [30 40 50 60 7 8 9]
c := a[2:6]
fmt.Printf(" len: %d, cap: %d , arr = %p , arr %+v \n", len(c), cap(c), c, c)
//len: 4, cap: 7 , arr = 0xc0000ba010 , arr [30 40 50 60]
}
summary :
How to calculate the length and Capacity
newslice := slice[ i : j ]
Without writing Default i = 0 , j = len(slice) k= cap(slice)
len(newslice) = j - i example: len(d) = 3 - 0 , len = 6-2
cap(newslice) = k - i example: len(d) = 9 -0 , len(b) = len = 9 - 2
Additional elements append()
a := []int{
1, 2, 3}
// Add... At the beginning 1 A slice
a = append([]int{
100, 200, 300}, a...)
fmt.Printf("a= len: %d, cap: %d , arr = %p , arr %+v \n", len(a), cap(a), a, a)
//a= len: 6, cap: 6 , arr = 0xc000196030 , arr [100 200 300 1 2 3]
// stay i=3 Add a slice to the location of the , Reallocated memory space
a = append(a[:3], append([]int{
1000, 2000}, a[3:]...)...)
fmt.Printf("a= len: %d, cap: %d , arr = %p , arr %+v \n", len(a), cap(a), a, a)
// a= len: 8, cap: 12 , arr = 0xc0001ae000 , arr [100 200 300 1000 2000 1 2 3]
b := append([]int{
666, 777}, a[4:]...) // Re unpacked
fmt.Printf("b= len: %d, cap: %d , arr = %p , arr %+v \n", len(b), cap(b), b, b)
//b= len: 6, cap: 6 , arr = 0xc000196090 , arr [666 777 2000 1 2 3]
// a It hasn't changed
fmt.Printf("a= len: %d, cap: %d , arr = %p , arr %+v \n", len(a), cap(a), a, a)
//a= len: 8, cap: 12 , arr = 0xc0001ae000 , arr [100 200 300 1000 2000 1 2 3]
// a Changed the ,a and c Point to the same memory space
c := append(a[:3], []int{
888, 999}...)
fmt.Printf("a= len: %d, cap: %d , arr = %p , arr %+v \n", len(a), cap(a), a, a)
//a= len: 8, cap: 12 , arr = 0xc0001ae000 , arr [100 200 300 888 999 1 2 3]
fmt.Printf("c= len: %d, cap: %d , arr = %p , arr %+v \n", len(c), cap(c), c, c)
//c= len: 5, cap: 12 , arr = 0xc0001ae000 , arr [100 200 300 888 999]
summary :
Inserting in the header will generally reallocate space , There is a copy of the array . In the middle of the slice , Or tail insertion will create a temporary slice , take a[i:] Copy the contents of , Then add it to a[:i]
Insert slices that do not create temporary slices :
copy(des,src) function
func testcopy() {
s1 := []int{
1, 2, 3}
s2 := []int{
4, 5}
s3 := []int{
6, 7, 8, 9}
// copy(s1, s2)
// fmt.Println(s1) //[4 5 3]
copy(s2, s1)
fmt.Println(s2) //[1.2]
copy(s2, s3)
fmt.Println(s2) //[6 7]
}
Use copy() function , Do not create temporary variables
copy(a[4:], a[3:]) // a[i:] Move backward 1 A place , The length remains the same , Remove one from the tail element
fmt.Printf(" len: %d, cap: %d , arr = %p , arr %+v \n", len(a), cap(a), a, a)
//len: 8, cap: 12 , arr = 0xc0001ae000 , arr [100 200 300 888 888 999 1 2]
// If you don't create a temporary variable
i := 2
x := []int{
101, 102, 103}
a = append(a, x...) // by x The slice expands enough space
copy(a[i+len(x):], a[i:]) // a[i:] Move backward len(x) A place
copy(a[i:], x) // Copy the newly added slice
Slice deletion
General deletion
var a = []int {
1,2,3}
a = a[ :len(a) - 1] // Delete the last element
a = a[ :len(a) - N] // Delete tail N Elements
a = a[1:] // Delete the head 1 Elements
a = a[N:] // Delete the head N Elements
Use append Complete in place : The so-called in-situ completion refers to the original Some slice data are completed in the corresponding memory interval , Will not cause memory space structure The change of
func removeSlice() {
var a = []int{
1, 2, 3, 4, 5}
fmt.Printf("removeSlice The original address = len: %d, cap: %d , arr = %p , arr %+v \n", len(a), cap(a), a, a)
//removeSlice The original address = len: 5, cap: 5 , arr = 0xc0000aa0f0 , arr [1 2 3 4 5]
a = a[:len(a)-1]
fmt.Printf("removeSlice Delete tail = len: %d, cap: %d , arr = %p , arr %+v \n", len(a), cap(a), a, a)
//removeSlice Delete tail = len: 4, cap: 5 , arr = 0xc0000aa0f0 , arr [1 2 3 4]
a = a[1:]
fmt.Printf("removeSlice Delete the head = len: %d, cap: %d , arr = %p , arr %+v \n", len(a), cap(a), a, a)
//removeSlice Delete the head = len: 3, cap: 4 , arr = 0xc0000aa0f8 , arr [2 3 4]
a = append(a[:0], a[1:]...)
fmt.Printf("removeSlice Delete the head = len: %d, cap: %d , arr = %p , arr %+v \n", len(a), cap(a), a, a)
//removeSlice Delete the head = len: 2, cap: 4 , arr = 0xc0000aa0f8 , arr [3 4]
}
summary :
Ordinary deletion will change the address , Data mobility , The capacity gets smaller , Use append There will be no change of position , The capacity will not change ( Here's why , It's not clear ), Use append More efficient
So delete the element
a = append(a[:i],a[i+1:]...)
a = append(a[:i],a[i+N:]...)
Efficient operation of slicing :
- To reduce the number of memory allocations , Try to make sure that append The operation will not exceed cap The capacity of , Reduce the number of times that trigger memory allocation
Number and size of memory allocated each time . - Avoid memory leaks , Although there is an automatic recycling mechanism , But when operating the pointer , You should still optimize your code , Tell the compiler to automatically reclaim the memory space to be released as soon as possible ,
func SliceDel() {
a := []*int{
}
b := 100
c := 10
a = append(a, &b, &c)
a[len(a)-1] = nil // Using the pointer object section , It is better to manually set it to nil, Ensure that the automatic collector can find the objects to be recycled
a = a[:len(a)-1]
}
- Slice type forced conversion . For the sake of safety , When two slice types []T and []Y The underlying primitive slice class Different types ,Go Languages cannot convert types directly . But security is there At a price , Sometimes this transformation has its value —— Can simplify the compilation of Code or improve the performance of code .
This Reading Note , read 《GO Language advanced programming 》 income , You can buy genuine books , It's still valuable .
版权声明
本文为[The interview was rejected 10000 times]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/04/202204231359046299.html
边栏推荐
- 聊一聊浏览器缓存控制
- Expression "func" tSource, object "to expression" func "tSource, object" []
- The new MySQL table has a self increasing ID of 20 bits. The reason is
- Set cell filling and ranking method according to the size of the value in the soft report
- DDT + Excel for interface test
- Log4j output log information to file
- Mock test
- 自定义my_strcpy与库strcpy【模拟实现字符串相关函数】
- Deeply understand the relevant knowledge of 3D model (modeling, material mapping, UV, normal), and the difference between displacement mapping, bump mapping and normal mapping
- How vscode compares the similarities and differences between two files
猜你喜欢
CentOS MySQL multi instance deployment
Set the color change of interlaced lines in cells in the sail software and the font becomes larger and red when the number is greater than 100
SQL database
STM32__03—初识定时器
RTKLIB 2.4.3源码笔记
VLAN高级技术,VLAN聚合,超级Super VLAN ,Sub VLAN
Modify the test case name generated by DDT
Rtklib 2.4.3 source code Notes
Use case execution of robot framework
英语 | Day15、16 x 句句真研每日一句(从句断开、修饰)
随机推荐
SQL database
5分钟NLP:Text-To-Text Transfer Transformer (T5)统一的文本到文本任务模型
DanceNN:字节自研千亿级规模文件元数据存储系统概述
Expression "func" tSource, object "to expression" func "tSource, object" []
PyTorch:train模式与eval模式的那些坑
Construction of promtail + Loki + grafana log monitoring system
On the security of key passing and digital signature
Disk management and file system
关于局域网如何组建介绍
Website_ Collection
Use case labeling mechanism of robot framework
如何建立 TikTok用户信任并拉动粉丝增长
File upload and download of robot framework
New project of OMNeT learning
OMNeT学习之新建工程
Change the password after installing MySQL in Linux
详解牛客----手套
Path environment variable
Linux MySQL data timing dump
About background image gradient()!