[go-nuts] how do I extend an array

6,985 views
Skip to first unread message

hotei

unread,
Apr 18, 2010, 9:11:43 PM4/18/10
to golang-nuts
I'm new to go, but have programmed in some other languages, including
python. I like what I've seen of go (A LOT!) but am having some
difficulty with the flexible size array behavior. Perhaps someone
with a bit more than my two weeks experience can suggest a solution.
I've included the python code in the simplest test case I could
formulate. Thanks.

package main
import (
"fmt"
)

/* Python flavor
array = [ 1 ]
print array
array.append(2)
print array
*/

func main() {
// make an array with capacity for 10 integers but assigning only one
value
array := make ([]int, 1, 10) ; array[0] = 1
fmt.Printf("array = %v\n", array) // ok so far...
array[1] = 2 // bombs
fmt.Printf("array = %v\n", array)
fmt.Printf("test fini\n")
}


--
Subscription settings: http://groups.google.com/group/golang-nuts/subscribe?hl=en

Andrew Gerrand

unread,
Apr 18, 2010, 9:28:45 PM4/18/10
to hotei, golang-nuts
First, what you're using there is a slice, not an array. The array is
the data structure behind the slice.

When you call make([]int, 1, 10)
- an array of 10 ints is allocated
- a slice of length 1 and capacity 10 is created. It can be thought
of as a "smart pointer" to the array.

To do what you need, you want to 're-slice'. Modifying your example:

func main() {
s := make ([]int, 1, 10)
s[0] = 1
fmt.Printf("slice = %v\n", s)
s = s[0:2] // this resizes the slice to a length of 2
s[1] = 2
fmt.Printf("slice = %v\n", s)
}

Hope this helps,
Andrew

Xiance SI(司宪策)

unread,
Apr 18, 2010, 10:04:15 PM4/18/10
to Andrew Gerrand, hotei, golang-nuts
Extendable array is very convenient, is there any easier and eligant way to append
a value to an array, and re-allocate the underlying array when it's full?

Andrew Gerrand

unread,
Apr 18, 2010, 10:08:18 PM4/18/10
to Xiance SI(司宪策), hotei, golang-nuts
On 19 April 2010 12:04, Xiance SI(司宪策) <ada...@gmail.com> wrote:
> Extendable array is very convenient, is there any easier and eligant way to
> append
> a value to an array, and re-allocate the underlying array when it's full?

You can implement a function to do so, tailored to your application.

There's an example of this in Effective Go:

http://golang.org/doc/effective_go.html#slices

Andrew

Steven

unread,
Apr 18, 2010, 10:39:25 PM4/18/10
to golang-nuts
On Sun, Apr 18, 2010 at 10:08 PM, Andrew Gerrand <a...@golang.org> wrote:
On 19 April 2010 12:04, Xiance SI(司宪策) <adam.si@gmail.com> wrote:
> Extendable array is very convenient, is there any easier and eligant way to
> append
> a value to an array, and re-allocate the underlying array when it's full?

You can implement a function to do so, tailored to your application.

There's an example of this in Effective Go:

http://golang.org/doc/effective_go.html#slices


You could also try a vector:

Note that aside from IntVector and StringVector, the current lack of generics in Go mean that it's up to you to ensure that a given vector has a consistent type. 

Hans Stimer

unread,
Apr 18, 2010, 11:58:01 PM4/18/10
to Steven, golang-nuts
It seems like there should be an easier mechanism given that a slice carries around a length, capacity, and reference to the underlying data.

Why not a setLen(slice, len) function?

Hans Stimer

unread,
Apr 19, 2010, 12:13:57 AM4/19/10
to Steven, golang-nuts
Neve rmind, I guess assigning a slice to itself isn't really much of burden.

s = s[0:newlen]

Xiance, there a variety of reasons not to automatically reallocate the underlying storage. The primary is performance. 

Xiance SI(司宪策)

unread,
Apr 19, 2010, 12:34:22 AM4/19/10
to Hans Stimer, Steven, golang-nuts
Thanks Hans,I understood the primary target :) Seems container.vector
and container.list are  good candidates for dynamic growing data collection.

Xiance

Ziad Hatahet

unread,
Apr 19, 2010, 2:11:34 AM4/19/10
to hotei, golang-nuts
FYI, the Python example you gave actually uses a list structure, not an array.


--
Ziad.

Noah Evans

unread,
Apr 19, 2010, 4:19:18 AM4/19/10
to golang-nuts
Here's one trick from the parser package(see parser.go) that might
give you a feel of how to do things:

var list vector.Vector
...
for ... {
...
list.Push(thing)
}

// convert list
group := make([]stuff, len(list))
for i, x := range list {
group[i] = x.(stuff)

Marcin 'Qrczak' Kowalczyk

unread,
Apr 19, 2010, 4:30:28 AM4/19/10
to Ziad Hatahet, hotei, golang-nuts
2010/4/19 Ziad Hatahet <hat...@gmail.com>:

> FYI, the Python example you gave actually uses a list structure, not an
> array.

Python calls it a list, but it corresponds to what most languages call
an array or vector.

--
Marcin Kowalczyk

Xiance SI(司宪策)

unread,
Apr 19, 2010, 11:47:47 AM4/19/10
to Noah Evans, golang-nuts
Thanks Noah :) This fits well when we need an expandable
list and later need to access via index number.

I'm wondering if a mixed list-vector type would be useful, like
ArrayList in Java.

Xiance

hotei

unread,
Apr 19, 2010, 1:22:01 PM4/19/10
to golang-nuts
Maybe, but with python you can still pick an item out of my list
example using an integer index. In python this operation succeeds
when the items are there and fails when they are not. For instance -
using my example - in python I can print array[0] and array[1] but it
fails when I try to print array[2] - which is roughly the same
behavior you get in go. This is good.



On Apr 19, 2:11 am, Ziad Hatahet <hata...@gmail.com> wrote:
> FYI, the Python example you gave actually uses a list structure, not an
> array.
>
> --
> Ziad.
>
Reply all
Reply to author
Forward
0 new messages