// A slice is a window on an underlying array
// Pointer, Length, Capacity
// They can be variable in length!
package main

import "fmt"

// file & package level variable
var myArray = [...]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}

func main() {
	fmt.Println(myArray)
	//slices can overlap. Since they are a pointer to an underlying arrary. They are mutable.
	s1 := myArray[0:6]
	s2 := myArray[5:len(myArray)]
	fmt.Println(s1)
	fmt.Println(s2)
	myArray[5] = 1337
	fmt.Println(myArray)
	fmt.Println(s1)
	fmt.Println(s2)
	// Writing to a slice changes the underlying arrary
	s1[5] = 7331
	fmt.Println(myArray)
	fmt.Println(s1)
	fmt.Println(s2)

	// Initializing a slice creates and underlying arrary
	var s3 []string
	s3 = append(s3, "Hello")
	s3 = append(s3, "Dirp")
	fmt.Println(s3, len(s3), cap(s3))

	// Another way to make an empty slice with a particular starting size
	s4 := make([]int, 100) // third arg is capacity otherwise len = cap in this invocation
	fmt.Println(s4)

	// gotcha
	fmt.Printf("S2 Len: %d Cap: %d\n", len(s2), cap(s2))
	// This increased the cap of the slice which meant a new array was created.
	// Now what was the overlapping element between s1 and s2 point to different arrays.
	// So changing the first element of s2 no longer updates the last elment of s1.
	s2 = append(s2, 100)
	fmt.Printf("S2 Len: %d Cap: %d\n", len(s2), cap(s2))
	s2[0] = 9000
	fmt.Println(s1)
	fmt.Println(s2)
}