code: func forEachUnpack(t Type, output []byte, start, size int) (interface{}, error) {
  	if size < 0 {
  		return nil, fmt.Errorf("cannot marshal input to array, size is negative (%d)", size)
  	}
  	if start+32*size > len(output) {
  		return nil, fmt.Errorf("abi: cannot marshal in to go array: offset %d would go over slice boundary (len=%d)", len(output), start+32*size)
  	}
  
  	// this value will become our slice or our array, depending on the type
  	var refSlice reflect.Value
  
  	if t.T == SliceTy {
  		// declare our slice
  		refSlice = reflect.MakeSlice(t.Type, size, size)
  	} else if t.T == ArrayTy {
  		// declare our array
  		refSlice = reflect.New(t.Type).Elem()
  	} else {
  		return nil, fmt.Errorf("abi: invalid type in array/slice unpacking stage")
  	}
  
  	// Arrays have packed elements, resulting in longer unpack steps.
  	// Slices have just 32 bytes per element (pointing to the contents).
  	elemSize := getTypeSize(*t.Elem)
  
  	for i, j := start, 0; j < size; i, j = i+elemSize, j+1 {
  		inter, err := toGoType(i, *t.Elem, output)
  		if err != nil {
  			return nil, err
  		}
  
  		// append the item to our reflect slice
  		refSlice.Index(j).Set(reflect.ValueOf(inter))
  	}
  
  	// return the interface
  	return refSlice.Interface(), nil
  }
docs: // iteratively unpack elements