29

I would like to build a function that returns a slice of any size. I know I can do

func BuildSlice() [100]int { return [100]int{} }

but I would like to be able to return slices of different sizes from the same function. Something like:

func BuildSlice(int size) [...]int { return [size]int{} }

I've tried the above as well as

func BuildSlice(size int) []int { return [size]int{} }

Please point me in the right direction.

vvvvv
  • 25,404
  • 19
  • 49
  • 81
Daniel Nill
  • 5,539
  • 10
  • 45
  • 63
  • 7
    First of all, `[100]int` is not a slice, it's an array. `[]int` is a slice. Please consider reading http://blog.golang.org/slices and http://blog.golang.org/go-slices-usage-and-internals – Kavu Mar 11 '14 at 05:59
  • You are profoundly mixing arrays and slices. Additional to the blog post mentioned by Kavu work your way through the tour of Go at http://tour.golang.org/#1 and effective Go http://golang.org/doc/effective_go.html – Volker Mar 11 '14 at 06:06
  • To clarify in short what the other comments have referred to: A `slice` is a scoped view of an array. The array can either be explicit, as in: `var a [100]int` - **array** of int, len==100 , `s := a[25:50]` - **slice** of `a`, giving access to elements 25.. **49** of `a` , or implicit, as in: `s := make([]int, 10, 100)` - slice with access to 10 elements of the array implicitly allocated by the second parameter of `make()` - `capacity`. – Vector Mar 11 '14 at 07:51

2 Answers2

54

First of all, slices are already of "variable size": [100]int and [...]int are array type definitions.

[]int is the correct syntax for a slice, and you could implement the function as:

func BuildSlice(size int) []int {
    return make([]int, size)
}

This will return a slice of zero values with the desired size, similar to what your array version does.

James Henstridge
  • 42,244
  • 6
  • 132
  • 114
5

The Go Programming Language Specification

Making slices, maps and channels

The built-in function make takes a type T, which must be a slice, map or channel type, optionally followed by a type-specific list of expressions. It returns a value of type T (not *T). The memory is initialized as described in the section on initial values.

Call Type T Result

make(T, n)       slice      slice of type T with length n and capacity n
make(T, n, m)    slice      slice of type T with length n and capacity m

The size arguments n and m must be of integer type or untyped. A constant size argument must be non-negative and representable by a value of type int. If both n and m are provided and are constant, then n must be no larger than m. If n is negative or larger than m at run time, a run-time panic occurs.

s := make([]int, 10, 100)       // slice with len(s) == 10, cap(s) == 100
s := make([]int, 1e3)           // slice with len(s) == cap(s) == 1000
s := make([]int, 1<<63)         // illegal: len(s) is not representable by a value of type int
s := make([]int, 10, 0)         // illegal: len(s) > cap(s)

For example,

package main

import "fmt"

func main() {
    s := make([]int, 7, 42)
    fmt.Println(len(s), cap(s))
    t := make([]int, 100)
    fmt.Println(len(t), cap(t))
}

Output:

7 42
100 100
peterSO
  • 158,998
  • 31
  • 281
  • 276