The reason []T (a slice of a specific type) cannot be directly converted to []interface{} is because the memory layout of the underlying array is not compatible with storing elements of different types.
When you have a slice []T, the memory layout of the underlying array is designed to store elements of type T. Each element in the array occupies a specific amount of memory based on its type T.
If you were allowed to convert []T to []interface{}, it would mean that the memory layout of the underlying array should be able to accommodate elements of any type, including interface{}. However, the original underlying array was designed to store elements of type T, not interface{} or any other type.
The issue is that the memory layout of the underlying array cannot simultaneously satisfy the requirements of different types. For example, if the original slice was []string, the memory layout of the underlying array is optimized for storing strings.
If you were able to convert []string to []interface{}, and then try to store elements of a different type (e.g., int) in the same underlying array, it would lead to an invalid memory layout. The memory allocated for strings would not be appropriate for storing int values, and accessing those values as interface{} could result in unexpected behavior or crashes.
To preserve type safety and maintain the integrity of the memory layout, Go requires you to manually create a new slice of []interface{} and copy the elements from the original slice, performing the necessary conversions. This ensures that the memory layout of the new slice is appropriate for interface{} values and avoids conflicting memory layouts or type mismatches.
So, in summary, the conversion from []T to []interface{} is not allowed because the memory layout of the underlying array is specific to the element type T, and it cannot be reconfigured to accommodate elements of different types without causing memory layout conflicts or type mismatches.