25

I am from a C background and passing an array in C style causes an error.

package main
import "fmt"

func f(a *int){
  fmt.Println(a[1])
}

func main(){
  var a [100]int
  a[1]=100
  f(a)
}

Error:: cannot use a (type [100]int) as type *int in argument to f

4
  • 5
    The Go Tutorial will cover this for you. Commented Aug 2, 2016 at 22:29
  • 4
    an array and a pointer are just plain not the same type, or convertible types, in Go. What you probably really want is a slice, which is like a view on an array. Commented Aug 2, 2016 at 22:30
  • Try this: gobyexample.com Commented Aug 2, 2016 at 22:45
  • To reinforce other comments, you most likely want a slice. A slice is very little more than a pointer to the beginning of an array and what gets passed in would just be that lightweight struct. I believe the correct term for this struct is the 'slice header' and it consists of; an int for the length, an int for capacity and a pointer to the underlying array. Commented Aug 2, 2016 at 23:22

5 Answers 5

30

As others have mentioned in comments, you probably want to use a slice rather than an array. Slices are passed by reference already, so no need to specify pointers. The make statement below creates a slice of ints (backed by an array). In the code below, I gave it a length of 2 and a capacity of 100 in order to satisfy your goal of assigning to index 1.

import (
    "fmt"
)

func f(a []int) {
    fmt.Println(a[1])
}

func main() {
    a := make([]int, 2, 100)
    a[1] = 100
    f(a)
}
Sign up to request clarification or add additional context in comments.

3 Comments

Technically, slices are passed by value, but their value is just a length and a pointer to an array.
Yes even slices are passed by value. As a slice will contain pointer to array. The data modified inside the function will affect the actual array
I dont think this works, I cannot modify the a inside f...
10

To answer the original question, you can pass a pointer to the array, to pass the array by reference.

For example, the following function changes the contents of an array of 3 integers.

func change(ptr *[3]int) {
    ptr[2] = 20
}

You can call this by passing a pointer to the original array:

change(&arr)

Complete Example:

package main

import (
    "fmt"
)

func main() {
    grades := [3]int {1, 2, 3}

    fmt.Printf("\nOriginal array:\n")
    for i, v := range grades {
        fmt.Printf("arr[%d] = %d\n", i, v)    // prints 1 2 3
    }

    change(&grades)
    fmt.Printf("\nModified grades:\n")
    for i, v := range grades {
        fmt.Printf("arr[%d] = %d\n", i, v)    // prints 1 2 20
    }
}

func change(ptr*[3]int) {
    ptr[2] = 20
}

In your example, f is expecting a pointer to an integer,

func f(a *int)    // a points to an integer

and you are passing it an array,

var a [100]int
f(a)

hence it gives you the error cannot use a (type [100]int) as type *int in argument to f.

Although passing a pointer to an array is efficient and allows the called function to change the caller’s variable, arrays are still fixed in size. Hence, slices are recommended, which are passed by reference and are dynamic in size.

1 Comment

do I really need to know the size of the list and put it in the signature?
2

you must use a slice instead of an array as argument of function. for example:

func p(a int){
fmt.Println(a)
}
func main() {
    var a = make([]int,2,10) //2 is length, 10 is capacity
    a[0] = 10
    p(a[0])
}

array is value type, slice is reference type. you can see more at https://blog.golang.org/go-slices-usage-and-internals

Wish it help you!

Comments

1

The go arrays have limited functionality. In C/C++ when you pass an array to a function the address of the 0th index will be passed but in case of go the complete array will be copied. If you print the address of the array in main and f you can see they will be different if you pass an array. What you can do, is from your array a you can create a slice using a[:]. When slice is passed the value of slice is copied as slice contains pointer to a any changes you do in f will reflect in the original array a.

package main
import "fmt"

func f(a []int){
  fmt.Println(a[1])
}

func main(){
  var a [100]int
  a[1]=100
  //Create a slice and pass it
  f(a[:])

}

Comments

0

I do not think any of the asweres above works. I found out that i either want to do a global varialbe of type []int or i have to wrap it in custom type like

type wrapper struct {
    data []int
}

func f(w *wrapper) {
    w.data[0] += 1
    w.data = append(w.data, 3)
}

func main() {
    w := wrapper{}
    w.data = append(w.data, 3)
    fmt.Println(w.data)
    f(&w)
    fmt.Println(w.data)
}

With passing a pointer to my wrapper i was able to avoid passing the size of the array/slice as well as using a global variable.

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.