Deep understanding of the slice of the Go language

Source: Internet
Author: User
This is a creation in Article, where the information may have evolved or changed.

Look at this code first, and the result is [0 2 3] that a lot of people can answer it correctly.

func modify(s []int) {    s[0] = 0}func main() {    s := []int{1, 2, 3}    modify(s)    fmt.Println(s)}

Then change it a little bit and guess the result.

func pop(s []int) {    s = s[:len(s)-1]}func main() {    s := []int{1, 2, 3}    pop(s)    fmt.Println(s)}

If you think the output [1 2] then you are wrong, and the result is [1 2 3] , you may find it strange that slice is a reference to semantics which in the first example has proved, why the second example is not so.

We'll add some output to the intermediate process, and then we'll look at

func pop(s []int) {    fmt.Printf("[pop] s addr:%p\n", &s)    s = s[:len(s)-1]    fmt.Println("[pop] s value:", s)}func main() {    s := []int{1, 2, 3}    fmt.Printf("[main] s addr:%p\n", &s)    pop(s)    fmt.Println("[main] s value:", s)}

Run the above code output as follows

[main] s addr:0xc082004640[pop] s addr:0xc0820046c0[pop] s value: [1 2][main] s value: [1 2 3]

To see the above results, it is possible to know that pop() the s reference is not a copy, although the pop() internal modification succeeds, but does not affect the main() in s . But the first example has been modified, and that's why.

The following is a look at the implementation of slice, you can clearly understand the reason.
The slice is implemented by fixed-length arrays. When adding elements to slice using the built-in function append() , the space is redistributed if the underlying array length is exceeded (similar to the vector for C + +).
Slice can be thought of as the following structure (regardless of the slice capacity). Lenghtrepresents the length of the slice, ' zerothelement represents the head pointer of the underlying array

type sliceHeader struct {    Length        int    ZerothElement *byte}

Referring to the definition of this struct and the following description, it is clear to understand the two examples of the beginning.

What if we need to pass slice as a function parameter and the function modifies slice? Here are three ways to say it.
1. Use the slice pointer as a parameter instead of slice

func modify(s *[]int) {    // do something}

2. Make the modified slice in the function as the return value, assign the function return value to the original slice

func modify(s []int) []int {    // do something    return s}func main() {    s := []int{1, 2, 3}    s = modify(s)}

3. How to make a function as a slice pointer

type slice []intfunc (s *slice) modify() {    // do something}
Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.