-2

I would prefer to pass potentially large arrays to standard functions that only take an array type, by reference, to avoid copying the array each time.

For example the crypto/sha256 packages Sum256() function https://golang.org/src/crypto/sha256/sha256.go?s=5634:5669#L244:

func Sum256(data []byte) [Size]byte 

My data could be large and I am worried about copying by value.. Looks like I can pass a slice and the compiler is happy with that but I'm unsure if that will still copy the underlying array by value..

markmnl
  • 11,116
  • 8
  • 73
  • 109
  • 3
    A slice is three machine words: pointer to backing array, length and capacity. The slice is copied in the call, but not the backing array. The function shown in the question has a slice argument, not an array argument. – Charlie Tumahai Jan 25 '20 at 07:18
  • Cool sounds like passing a slice is the way to go, if you put in an answer I would mark it :) – markmnl Jan 25 '20 at 07:25
  • 2
    Possible duplicate of [Are golang slices passed by value?](https://stackoverflow.com/questions/39993688/are-golang-slices-passed-by-value), [Does slice assignment in Go copy memory](https://stackoverflow.com/questions/55228174/does-slice-assignment-in-go-copy-memory), ... – Charlie Tumahai Jan 25 '20 at 07:29
  • Passing an array to a slice argument is a compilation error. Use a [slice expression](https://golang.org/ref/spec#Slice_expressions) to create a slice on the array. Separate the call issue, it sounds like you should be using a slice instead of an array. Slices are typically used when the length is large or the size is unknown. – Charlie Tumahai Jan 25 '20 at 07:34
  • If your `data` is large and you are streaming it (e.g. from a file, http response...) you can also see [this example `(Example (File))`](https://pkg.go.dev/crypto/sha256?tab=doc#example-New-File) about getting a hash from a file without loading everything into memory – xarantolus Jan 25 '20 at 07:48
  • Additionaly there simply is **no** "pass by referemce" in Go as there are no references in Go. Everything is passed by value, even pointers. – Volker Jan 25 '20 at 08:37
  • 2
    Does this answer your question? [Does slice assignment in Go copy memory](https://stackoverflow.com/questions/55228174/does-slice-assignment-in-go-copy-memory) – marco.m Jan 25 '20 at 08:55

1 Answers1

1

A slice is a struct that contains a pointer to an array (backing array), a length and a capacity. It describes a portion of an array. When you copy a slice, Go doesn't copy its backing array, Go only copies the slice.

// create an array of four bytes
dataArray := [4]byte{'d', 'a', 't', 'a'}

// get a slice of 'dataArray'.
// 'data' is just a struct that contains a pointer
// to the 'dataArray'. (data's backing array is
// dataArray).
data := dataArray[:]

// this only passes the `data`
// (which is a slice header of the data variable)
// it doesn't pass the `dataArray`.
//
// The only thing that is copied is the `data`
// (slice header) not the `dataArray`
// (the backing array of `data`).
sha256.Sum256(data)

If you're a visual learner, take a look at this video: https://www.youtube.com/watch?v=fF68HELl78E

Inanc Gumus
  • 25,195
  • 9
  • 85
  • 101