A Go slice is a lightweight descriptor containing a pointer to an underlying array, its length, and its capacity. It does not own the data; it only references a portion of an existing array. When you pass a slice to a function, you pass this descriptor by value, but the underlying array data is shared.
package main
import "fmt"
func main() {
arr := [5]int{1, 2, 3, 4, 5}
s := arr[1:4] // Pointer to arr[1], len=3, cap=4
fmt.Printf("Slice: %v\n", s) // [2 3 4]
fmt.Printf("Len: %d, Cap: %d\n", len(s), cap(s))
s[0] = 99 // Modifies underlying array
fmt.Printf("Array: %v\n", arr) // [1 99 3 4 5]
}