slice shift like function in go lang

user7014993 picture user7014993 · Mar 11, 2017 · Viewed 9.1k times · Source

how array shift function works with slices?

package main

import "fmt"

func main() {
    s := []int{2, 3, 5, 7, 11, 13}

    for k, v := range s {
        x, a := s[0], s[1:] // get and remove the 0 index element from slice
        fmt.Println(a) // print 0 index element
    }
}

I found an example from slice tricks but can't get it right.

https://github.com/golang/go/wiki/SliceTricks

x, a := a[0], a[1:]

Edit can you please explain why x is undefined here?

Building upon the answer and merging with SliceTricks

import "fmt"

func main() {
    s := []int{2, 3, 5, 7, 11, 13}
    fmt.Println(len(s), s)
    for len(s) > 0 {
    x, s = s[0], s[1:] // undefined: x
        fmt.Println(x) // undefined: x
    }
    fmt.Println(len(s), s)
}

Answer

peterSO picture peterSO · Mar 11, 2017

For example,

package main

import "fmt"

func main() {
    s := []int{2, 3, 5, 7, 11, 13}
    fmt.Println(len(s), s)
    for len(s) > 0 {
        x := s[0]      // get the 0 index element from slice
        s = s[1:]      // remove the 0 index element from slice
        fmt.Println(x) // print 0 index element
    }
    fmt.Println(len(s), s)
}

Output:

6 [2 3 5 7 11 13]
2
3
5
7
11
13
0 []

References:

The Go Programming Language Specification: For statements


Addendum to answer edit to question:

Declare x,

package main

import "fmt"

func main() {
    s := []int{2, 3, 5, 7, 11, 13}
    fmt.Println(len(s), s)
    for len(s) > 0 {
        var x int
        x, s = s[0], s[1:]
        fmt.Println(x)
    }
    fmt.Println(len(s), s)
}

Output:

6 [2 3 5 7 11 13]
2
3
5
7
11
13
0 []

You can copy and paste my code for any slice type; it infers the type for x. It doesn't have to be changed if the type of s changes.

for len(s) > 0 {
    x := s[0]      // get the 0 index element from slice
    s = s[1:]      // remove the 0 index element from slice
    fmt.Println(x) // print 0 index element
}

For your version, the type for x is explicit and must be changed if the type of s is changed.

for len(s) > 0 {
    var x int
    x, s = s[0], s[1:]
    fmt.Println(x)
}