不使用make创建Go切片

nums := []int{2, 3, 4}

What does this do in go? Am I creating an array or a slice?

From this: https://gobyexample.com/range, it says slice. But I think it is an array.

In go, array types include their length. Since you omitted the length it is a slice:

array := [3]int{1, 2, 3} // Array since it includes length (3).
slice := array[:] // Slice since there is no length specified.

fmt.Printf("%#v - %T
", slice, slice) // %T means "type".
fmt.Printf("%#v - %T
", array, array)
// [3]int{1, 2, 3} - [3]int
// []int{1, 2, 3} - []int

In the example above, we made a slice without invoking "make" by setting it to the full range of of array. If you were to edit either array or slice then both will change, since "slice" is essentially a view into the storage that is "array".

slice[0] = 456 // And array[0] == 456
array[0] = 789 // And slice[0] == 789

Since you didn't specify the length, it is a slice.

An array type definition specifies a length and an element type: see "Go Slices: usage and internals"

http://blog.golang.org/go-slices-usage-and-internals_slice-array.png

A slice literal is declared just like an array literal, except you leave out the element count.

While a slice can be created with the built-in function called make, you used the literal form to create a slice.

The internal of the created slice differs from an array:

make([]byte, 5)

http://blog.golang.org/go-slices-usage-and-internals_slice-1.png

Actually by doing this:

nums := []int{2, 3, 4}

You are creating both: an array and a slice. But since it is a slice literal, the result will be of slice type, so the type of nums is []int which you can verify with this code:

fmt.Printf("%T", nums) // Output: []int

What happens is that an array will be created/allocated automatically in the background with a length of 3 initialized with the listed elements, and a slice will be created referring to the array, and this slice will be the result of the expression.

Quoting from the Go Language Specification: Composite literals:

A slice literal describes the entire underlying array literal. Thus, the length and capacity of a slice literal are the maximum element index plus one. A slice literal has the form

[]T{x1, x2, … xn}

and is shorthand for a slice operation applied to an array:

tmp := [n]T{x1, x2, … xn}
tmp[0 : n]

An Array literal also includes the length, for example:

arr := [3]int{1, 2, 3}
arr2 := [...]int{1, 2, 3} // Length will be computed by the compiler
fmt.Printf("%T", arr)  // Output: [3]int
fmt.Printf("%T", arr2) // Output: [3]int