Slice is basically just a reference to the underlying array, start pointer, length and capacity. So if it would be possible, then consider the following:
sliceOfStrings := []string{"one", "two", "three"} // prints ONE TWO THREE for i := range sliceOfStrings { fmt.Println(strings.ToUpper(sliceOfStrings[i])) } // imagine this is possible var sliceOfInterface = []interface{}(sliceOfStrings) // since it's array of interface{} now - we can do anything // let's put integer into the first position sliceOfInterface[0] = 1 // sliceOfStrings still points to the same array, and now "one" is replaced by 1 fmt.Println(strings.ToUpper(sliceOfStrings[0])) // BANG!
This issue exists in Java and C#. In practice it happens rarely, but still. Given that in Go there is no automatic type conversions like int32 -> int64 it makes sense that you are forced to create a []interface{} copy if you really want to send []string as []interface{}. This way there can be no surprise - you wrote it explicitly, you know what you're doing. And if function will modify []interface{} - it won't hurt original []string.