114

I try to write a small application in go that takes 'x' numbers of integers from standard input, calculates the mean and gives it back. I have only gotten so far:

func main() {
var elems, mean int
sum := 0

fmt.Print("Number of elements? ")

fmt.Scan(&elems)

var array = new([elems]int)

for i := 0; i < elems; i++ {
    fmt.Printf("%d . Number? ", i+1)
    fmt.Scan(&array[i])
    sum += array[i];
}............

When trying to compile this I get the following error message:

invalid array bound elems

What is wrong here?

1

3 Answers 3

167

You should use a slice instead of an array:

//var array = new([elems]int) - no, arrays are not dynamic
var slice = make([]int,elems) // or slice := make([]int, elems)

See "go slices usage and internals". Also you may want to consider using range for your loop:

// for i := 0; i < elems; i++ { - correct but less idiomatic
for i, v := range slice {
Sign up to request clarification or add additional context in comments.

7 Comments

Thanks for the link! Exactly what I sought :)
@Paolo: You would need to write "for i,_ := range array {}". In my opinion, using "for i:=0; i<elems; i++ {}" seems more appropriate here. In either case, there is no need to use an array in this program.
@Atom: I thought he could use v instead of array[i] in the loop. But I agree that my search for idiomatic code is sometimes exaggerated (I'm one of those people who, when abroad, look for typical restaurants and get typically ripped off)
Should be slice := make([]int, elems) to avoid confusion.
if it's "dynamic", why we need to set the length of the slice?
|
23

In my opinion, this results from confusion over the usage of the new and make functions. This is a known issue/feature in the Go language, as evidenced by several discussions about new vs make at golang-nuts.

The difference between new and make may become clearer by letting Go print out the type of the value created by new and make:

package main

import "fmt"

func main() {
    fmt.Printf("%T  %v\n", new([10]int), new([10]int))
    fmt.Printf("%T  %v\n", make([]int, 10), make([]int, 10))
}

The output:

*[10]int  &[0 0 0 0 0 0 0 0 0 0]
[]int  [0 0 0 0 0 0 0 0 0 0]

As can be seen from the type, to access an array element of new([10]int) we would first need to dereference the pointer.

Both new and make require a Go type as their 1st argument. However, the expression [elems]int is not a Go type (unless elems is a Go constant, which isn't the case here).

For further reference, see http://golang.org/doc/go_spec.html#Allocation and http://golang.org/doc/go_spec.html#The_zero_value.

To get a better understanding of whether the result of new is usable, it may be helpful to lookup whether len and cap work with zero (nil) values: http://golang.org/doc/go_spec.html#Length_and_capacity

Comments

4

See The Go Programming Language Specification

http://golang.org/ref/spec#Array_types

http://golang.org/ref/spec#Constants

It says:"The length is part of the array's type; it must evaluate to a non- negative constant representable by a value of type int. "

Constants by no means vary.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.