search
HomeBackend DevelopmentGolangWhat is the difference between arrays and slices in go language?

What is the difference between arrays and slices in go language?

Jan 13, 2023 pm 05:26 PM
golanggo languagearrayslice

The difference between arrays and slices: 1. Slices are pointer types, arrays are value types; 2. The assignment form of arrays is value transfer, and the assignment form of slices is reference transfer; 3. The length of the array is fixed , and the slice length can be adjusted arbitrarily (the slice is a dynamic array); 4. The length of the array is fixed, but the slice length can be adjusted arbitrarily (the slice is a dynamic array).

What is the difference between arrays and slices in go language?

The operating environment of this tutorial: Windows 7 system, GO version 1.18, Dell G3 computer.

The array in Go language is roughly equivalent to the array in C/C, with a fixed size and cannot be dynamically expanded in size, while the slice is roughly equivalent to the Vector in C, which can be dynamically expanded in size , when the size exceeds the capacity, reallocate a piece of memory, and then copy the data to the new memory area. Let's go through a few questions to better understand golang's arrays and slices. Let's take a look.

1. Array

Go's slice is an abstract data type on top of the array, so you must first understand the array before understanding the slice .

1. Three ways to declare arrays

  • var identifier [len]type
  • var identifier = [len]type{value1 , value2, … , valueN}
  • var identifier = […]type{value1, value2, … , valueN}

Corresponding:

  • identifier := [len]type{}
  • identifier := [len]type{value1, value2, … , valueN}
  • identifier := […]type{value1, value2, …, valueN}

Example:

var iarray1 [5]int32
var iarray2 [5]int32 = [5]int32{1, 2, 3, 4, 5}
iarray3 := [5]int32{1, 2, 3, 4, 5}
iarray4 := [5]int32{6, 7, 8, 9, 10}
iarray5 := [...]int32{11, 12, 13, 14, 15}
iarray6 := [4][4]int32{{1}, {1, 2}, {1, 2, 3}}  

fmt.Println(iarray1)
fmt.Println(iarray2)
fmt.Println(iarray3)
fmt.Println(iarray4)
fmt.Println(iarray5)
fmt.Println(iarray6)

Result:

[0 0 0 0 0]
[1 2 3 4 5]
[1 2 3 4 5]
[6 7 8 9 10]
[11 12 13 14 15]
[[1 0 0 0] [1 2 0 0] [1 2 3 0] [0 0 0 0]]

We look at the array iarray1, which is only declared and not assigned. The Go language helps us automatically assign the value as 0. Looking at iarray2 and iarray3 again, we can see that the Go language declaration can indicate the type or not. var iarray3 = [5]int32{1, 2, 3, 4, 5} is also completely fine.

2. The capacity and length of the array

The capacity and length of the array are the same. Both the cap() function and the len() function output the capacity (i.e. length) of the array

3. Type

Arrays are value types. When assigning one array to another array, the passed It's a copy. While slices are reference types, the array wrapped by the slice is called the underlying array of the slice. Look at the following example:

//a是一个数组,注意数组是一个固定长度的,初始化时候必须要指定长度,不指定长度的话就是切片了
a := [3]int{1, 2, 3}
//b是数组,是a的一份拷贝
b := a
//c是切片,是引用类型,底层数组是a
c := a[:]
for i := 0; i < len(a); i++ {
 a[i] = a[i] + 1
}
//改变a的值后,b是a的拷贝,b不变,c是引用,c的值改变
fmt.Println(a) //[2,3,4]
fmt.Println(b) //[1 2 3]
fmt.Println(c) //[2,3,4]

2. Slicing

In Go language, a slice is an identical sequence of elements with variable length and fixed capacity. The essence of slice in Go language is an array. The capacity is fixed because the length of the array is fixed, and the capacity of the slice is the length of the hidden array. Variable length refers to being variable within the range of the array length.

1. Four ways to create slices

  • var slice1 = make([]int,5,10)
  • var slice2 = make([]int,5)
  • var slice3 = []int{}
  • var slice4 = []int{1,2,3,4,5}

Correspondingly:

  • slice1 := make([]int,5,10)
  • slice2 := make([]int,5)
  • slice3 := []int{}
  • slice4 := []int{1,2,3,4,5}

The corresponding output of the above

[0 0 0 0 0]
[0 0 0 0 0]
[]
[1 2 3 4 5]

It can be seen from 3) and 4) that the only difference between creating a slice and creating an array is whether there is a number in the "[]" before Type. If it is empty, it represents a slice, otherwise it represents an array. Because slices are of variable length

2. Hidden array

Go's slice is an abstract data type on top of the array, so the created slice always has a The array exists.

Example:

slice0 := []string{"a", "b", "c", "d", "e"}
slice1 := slice0[2 : len(slice0)-1]
slice2 := slice0[:3]
fmt.Println(slice0, slice1, slice2)
slice2[2] = "8"
fmt.Println(slice0, slice1, slice2)

Output:

[a b c d e] [c d] [a b c]
[a b 8 d e] [8 d] [a b 8]

It also shows that slices slice0, slice1 and slice2 are references to the same underlying array, so slice2 has changed, and the other two It will all change

3. append appends the slice

The built-in function append can append one or more other values ​​of the same type to a slice. If the number of appended elements exceeds the capacity of the original slice, what is finally returned is a brand new slice in a brand new array. If it does not exceed, then what is finally returned is a brand new slice in the original array. In any case, append has no effect on the original slice.

Example:

slice1 := make([]int, 2, 5)
fmt.Println(len(slice1), cap(slice1))
for k := range slice1{
    fmt.Println(&slice1[k])
}
slice1 = append(slice1,4)
fmt.Println(len(slice1), cap(slice1))
for k := range slice1{
    fmt.Println(&slice1[k])
}
slice1 = append(slice1,5,6,7)
fmt.Println(len(slice1), cap(slice1))
for k := range slice1{
    fmt.Println(&slice1[k])
}

Output:

2 5 //长度和容量
0xc420012150
0xc420012158

3 5 //第一次追加,未超出容量,所以内存地址未发生改变
0xc420012150
0xc420012158
0xc420012160

6 10 //第二次追加,超过容量,内存地址都发生了改变,且容量也发生了改变,且是原来的2倍
0xc4200100f0
0xc4200100f8
0xc420010100
0xc420010108
0xc420010110
0xc420010118

Look at another example:

slice1 := make([]int, 2, 5)
slice2 := slice1[:1]
fmt.Println(len(slice1), cap(slice1))
for k := range slice1{
    fmt.Println(&slice1[k])
}
fmt.Println(len(slice2), cap(slice2))
for k := range slice2{
    fmt.Println(&slice2[k])
}

slice2 = append(slice2,4,5,6,7,8)

fmt.Println(len(slice1), cap(slice1))
for k := range slice1{
    fmt.Println(&slice1[k])
}
fmt.Println(len(slice2), cap(slice2))
for k := range slice2{
    fmt.Println(&slice2[k])
}

The above output:

2 5 //slice1的长度和容量
0xc4200700c0
0xc4200700c8

1 5  //slice2的长度和容量
0xc4200700c0

2 5 //slice2追加后,slice1的长度和容量、内存都未发生改变
0xc4200700c0
0xc4200700c8

6 10 //slice2追加后,超过了容量,所以slice2的长度和容量、内存地址都发生改变。
0xc42007e000
0xc42007e008
0xc42007e010
0xc42007e018
0xc42007e020
0xc42007e028

3. GO The difference between arrays and slices

The following mainly looks at some practical examples to illustrate the difference between arrays and slices.

1. Assignment forms of arrays and slices

Example 1

arr1 := [3] int {1,2,3}
arr2 := arr1
for k := range arr1 {
    fmt.Printf("%v ",&arr1[k]);
}

fmt.Println("");

for k := range arr2 {
    fmt.Printf("%v ",&arr2[k]);
}

fmt.Println("\n=================");

slice1 := [] int{1,2,3}
slice2 := slice1
for k := range slice1 {
    fmt.Printf("%v ",&slice1[k]);
}
fmt.Println("");
for k := range slice2 {
    fmt.Printf("%v ",&slice2[k]);
}

输出结果:
0xc420014140 0xc420014148 0xc420014150 
0xc420014160 0xc420014168 0xc420014170 
=================
0xc4200141a0 0xc4200141a8 0xc4200141b0 
0xc4200141a0 0xc4200141a8 0xc4200141b0

As can be seen from this example, array The assignment is a copy of the value, which is a brand new array. The assignment of the slice is a reference . Let’s look at another example.

Example 2:

arr1 := [3] int {1,2,3}
arr2 := arr1
fmt.Printf("%v %v ",arr1,arr2);

arr1[0] = 11
arr2[1] = 22
fmt.Printf("\n%v %v ",arr1,arr2);

fmt.Println("\n================");

slice1 := [] int{1,2,3}
slice2 := slice1
fmt.Printf("%v %v ",slice1,slice2);

slice1[0] = 11
slice2[1] = 22
fmt.Printf("\n%v %v ",slice1,slice2);

输出结果:
[1 2 3] [1 2 3] 
[11 2 3] [1 22 3] 
================
[1 2 3] [1 2 3] 
[11 22 3] [11 22 3]

This example once again illustrates: arrays are assignments and copies, while slices are only references. The slice declarations in Examples 1 and 2 use hidden arrays. Let's look at Example 3 again, using a non-hidden array.

Example 3:

arr1 := [5] int {1,2,3}
slice1 := arr1[0:3]
slice2 := slice1[0:4]

fmt.Printf("len: %d cap: %d %v\n",len(arr1),cap(arr1),arr1); //打印出非隐藏数组
for k := range arr1 {
    fmt.Printf("%v ",&arr1[k]);
}

fmt.Println("");

fmt.Printf("len: %d cap: %d %v\n",len(slice1),cap(slice1),slice1); //打印切片1
for k := range slice1 {
    fmt.Printf("%v ",&slice1[k]);
}

fmt.Println("");

fmt.Printf("len: %d cap: %d %v\n",len(slice2),cap(slice2),slice2); //打印切片2
for k := range slice2 {
    fmt.Printf("%v ",&slice2[k]);
}
fmt.Println("\n=================");

arr1[0] = 11   //非隐藏数组、切片1、切片2各自发生更改
slice1[1] = 22
slice2[2] = 33

fmt.Printf("len: %d cap: %d %v\n",len(arr1),cap(arr1),arr1); //再次打印非隐藏数组
for k := range arr1 {
    fmt.Printf("%v ",&arr1[k]);
}

fmt.Println("");

fmt.Printf("len: %d cap: %d %v\n",len(slice1),cap(slice1),slice1); //再此打印切片1
for k := range slice1 {
    fmt.Printf("%v ",&slice1[k]);
}
fmt.Println("");

fmt.Printf("len: %d cap: %d %v\n",len(slice2),cap(slice2),slice2); //再次打印切片2
for k := range slice2 {
    fmt.Printf("%v ",&slice2[k]);
}

输出结果:
len: 5 cap: 5 [1 2 3 0 0]0xc420012150 0xc420012158 0xc420012160 0xc420012168 0xc420012170 
len: 3 cap: 5 [1 2 3]0xc420012150 0xc420012158 0xc420012160 len: 4 cap: 5 [1 2 3 0]0xc420012150 0xc420012158 0xc420012160 0xc420012168 
=================
len: 5 cap: 5 [11 22 33 0 0]
0xc420012150 0xc420012158 0xc420012160 0xc420012168 0xc420012170 
len: 3 cap: 5 [11 22 33]
0xc420012150 0xc420012158 0xc420012160 
len: 4 cap: 5 [11 22 33 0]
0xc420012150 0xc420012158 0xc420012160 0xc42001216

To sum up the above three examples, it can be seen that slices are references to arrays, including references to hidden arrays and non-hidden arrays.

2. The array is used as a parameter and is called by the function

func Connect() {
    arr1 := [5] int {1,2,3}
    fmt.Printf("%v ",arr1);
    for k := range arr1 {
        fmt.Printf("%v ",&arr1[k]);
    }
    fmt.Println("");
    f1(arr1)
    fmt.Println("");
    f2(&arr1)
}
func f1(arr [5]int) {
    fmt.Printf("%v ",arr);
    for k := range arr {
        fmt.Printf("%v ",&arr[k]);
    }
}
func f2(arr *[5]int) {
    fmt.Printf("%v ",arr);
    for k := range arr {
        fmt.Printf("%v ",&arr[k]);
    }
}

输出结果:
[1 2 3 0 0]  0xc420012150 0xc420012158 0xc420012160 0xc420012168 0xc420012170 
[1 2 3 0 0]  0xc4200121b0 0xc4200121b8 0xc4200121c0 0xc4200121c8 0xc4200121d0 
&[1 2 3 0 0] 0xc420012150 0xc420012158 0xc420012160 0xc420012168 0xc420012170

从上面的例子可以看出,数组在参数中,可以使用值传递和引用传递。值传递会拷贝新数组,引用传递则使用原数组。

func Connect() {
    slice1 := [] int {1,2,3}
    fmt.Printf("%v ",slice1);
    for k := range slice1 {
        fmt.Printf("%v ",&slice1[k]);
    }
    fmt.Println("");
    f1(slice1)
}
func f1(slice []int) {
    fmt.Printf("%v ",slice);
    for k := range slice {
        fmt.Printf("%v ",&slice[k]);
    }
}

输出结果:
[1 2 3] 0xc420014140 0xc420014148 0xc420014150 
[1 2 3] 0xc420014140 0xc420014148 0xc42001415

从这个例子中可以看出,切片在参数中传递本身就引用。

总结:

  • 切片是指针类型,数组是值类型

  • 数组的赋值形式为值传递,切片的赋值形式为引用传递

  • 数组的长度是固定的,而切片长度可以任意调整(切片是动态的数组)

  • 数组只有长度一个属性,而切片比数组多了一个容量(cap)属性

【相关推荐:Go视频教程编程教学

The above is the detailed content of What is the difference between arrays and slices in go language?. For more information, please follow other related articles on the PHP Chinese website!

Statement
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Golang vs. Python: Concurrency and MultithreadingGolang vs. Python: Concurrency and MultithreadingApr 17, 2025 am 12:20 AM

Golang is more suitable for high concurrency tasks, while Python has more advantages in flexibility. 1.Golang efficiently handles concurrency through goroutine and channel. 2. Python relies on threading and asyncio, which is affected by GIL, but provides multiple concurrency methods. The choice should be based on specific needs.

Golang and C  : The Trade-offs in PerformanceGolang and C : The Trade-offs in PerformanceApr 17, 2025 am 12:18 AM

The performance differences between Golang and C are mainly reflected in memory management, compilation optimization and runtime efficiency. 1) Golang's garbage collection mechanism is convenient but may affect performance, 2) C's manual memory management and compiler optimization are more efficient in recursive computing.

Golang vs. Python: Applications and Use CasesGolang vs. Python: Applications and Use CasesApr 17, 2025 am 12:17 AM

ChooseGolangforhighperformanceandconcurrency,idealforbackendservicesandnetworkprogramming;selectPythonforrapiddevelopment,datascience,andmachinelearningduetoitsversatilityandextensivelibraries.

Golang vs. Python: Key Differences and SimilaritiesGolang vs. Python: Key Differences and SimilaritiesApr 17, 2025 am 12:15 AM

Golang and Python each have their own advantages: Golang is suitable for high performance and concurrent programming, while Python is suitable for data science and web development. Golang is known for its concurrency model and efficient performance, while Python is known for its concise syntax and rich library ecosystem.

Golang vs. Python: Ease of Use and Learning CurveGolang vs. Python: Ease of Use and Learning CurveApr 17, 2025 am 12:12 AM

In what aspects are Golang and Python easier to use and have a smoother learning curve? Golang is more suitable for high concurrency and high performance needs, and the learning curve is relatively gentle for developers with C language background. Python is more suitable for data science and rapid prototyping, and the learning curve is very smooth for beginners.

The Performance Race: Golang vs. CThe Performance Race: Golang vs. CApr 16, 2025 am 12:07 AM

Golang and C each have their own advantages in performance competitions: 1) Golang is suitable for high concurrency and rapid development, and 2) C provides higher performance and fine-grained control. The selection should be based on project requirements and team technology stack.

Golang vs. C  : Code Examples and Performance AnalysisGolang vs. C : Code Examples and Performance AnalysisApr 15, 2025 am 12:03 AM

Golang is suitable for rapid development and concurrent programming, while C is more suitable for projects that require extreme performance and underlying control. 1) Golang's concurrency model simplifies concurrency programming through goroutine and channel. 2) C's template programming provides generic code and performance optimization. 3) Golang's garbage collection is convenient but may affect performance. C's memory management is complex but the control is fine.

Golang's Impact: Speed, Efficiency, and SimplicityGolang's Impact: Speed, Efficiency, and SimplicityApr 14, 2025 am 12:11 AM

Goimpactsdevelopmentpositivelythroughspeed,efficiency,andsimplicity.1)Speed:Gocompilesquicklyandrunsefficiently,idealforlargeprojects.2)Efficiency:Itscomprehensivestandardlibraryreducesexternaldependencies,enhancingdevelopmentefficiency.3)Simplicity:

See all articles

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

AI Hentai Generator

AI Hentai Generator

Generate AI Hentai for free.

Hot Article

R.E.P.O. Energy Crystals Explained and What They Do (Yellow Crystal)
1 months agoBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Best Graphic Settings
1 months agoBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. How to Fix Audio if You Can't Hear Anyone
1 months agoBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Chat Commands and How to Use Them
1 months agoBy尊渡假赌尊渡假赌尊渡假赌

Hot Tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

PhpStorm Mac version

PhpStorm Mac version

The latest (2018.2.1) professional PHP integrated development tool

Safe Exam Browser

Safe Exam Browser

Safe Exam Browser is a secure browser environment for taking online exams securely. This software turns any computer into a secure workstation. It controls access to any utility and prevents students from using unauthorized resources.

SublimeText3 Linux new version

SublimeText3 Linux new version

SublimeText3 Linux latest version

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

This project is in the process of being migrated to osdn.net/projects/mingw, you can continue to follow us there. MinGW: A native Windows port of the GNU Compiler Collection (GCC), freely distributable import libraries and header files for building native Windows applications; includes extensions to the MSVC runtime to support C99 functionality. All MinGW software can run on 64-bit Windows platforms.