Write a version of rotate that operates in a single pass

I am currently reading *** Go Programming Language, by Alan Donovan***. In chapter 4, I stuck in some code of exercise 4.4 which state that “Write a version of rotate that operates in a single pass?” I want to write it with a little modification with number of left rotations.

package main
import(
  "fmt"
)

func rotate(s []int,shift int){
   first := s[:shift]
   copy(s,s[shift:])   // This change the values of first
   s[len(s)-shift]=first  // This doesn't work !!!
}

func main() {
   data := []int{1,2,3,4,5,6}
   left_shift := 3
   rotate(data,left_shift)  // 4 5 6 1 2 3	
   fmt.Println(data)
}

Can anyone help me to understand concepts of Slices.

slices are pointers to an special structure (https://blog.golang.org/slices-intro), so first is just a pointer to slice contents, if you change it, also the contents of first because it points to same address.
So you can use this code to do what you want to do:

func rotate(s []int, shift int) {
   slc3 := make([]int, 0)
   slc3 = append(slc3, s[shift:]...)
   slc3 = append(slc3, s[:shift]...)
   copy(s, slc3)
}

Even though the size of the slice didn’t get changed, initial array remains untouched even after an operation.

https://play.golang.org/p/K0SFXLddsRy

Can you explain here

I found a good blog article in the docs about this behavior: https://blog.golang.org/slices#TOC_4.

I know append says if the length is unchanged its modifies the underlying array but that doesn’t seem to be happening in your playground example.

yes. I’m not getting an expected behaviour in my case.

Later after some more reading I understood how slice work. So I have also write my version of rotate function which is O(n) space complexity.

// space is O(n)
func rotate(s []int,shift int)[]int{
    var newdata []int
    first := s[:shift]
    newdata = append(newdata,s[shift:]...)
    newdata = append(newdata,first...)
    return newdata
}	
func main(){
    data := []int{1,2,3,4,5,6}
    left_shift := 3
    fmt.Println(rotate(data,left_shift))  // 4 5 6 1 2 3
}

I was trying to do this same with O(1) space. Does it possible?