Repository: go
Issue: x/mobile: Issues converting Data to []byte in Swift
Labels: ExpertNeeded,NeedsInvestigation,mobile

<!-- Please answer these questions before submitting your issue. Thanks! -->

### What version of Go are you using (`go version`)?

<pre>
$ go version
go version go1.12.9 darwin/amd64
</pre>

### Does this issue reproduce with the latest release?

Yes.

### What operating system and processor architecture are you using (`go env`)?

<details><summary><code>go env</code> Output</summary><br><pre>
$ go env
GOARCH="amd64"
GOBIN=""
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOOS="darwin"
GOPROXY=""
GORACE=""
GOROOT="/usr/local/Cellar/go/1.12.9/libexec"
GOTMPDIR=""
GOTOOLDIR="/usr/local/Cellar/go/1.12.9/libexec/pkg/tool/darwin_amd64"
GCCGO="gccgo"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
GOMOD=""
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/gg/29c0x6691455vgkxwl2hrpgc0000gn/T/go-build354245371=/tmp/go-build -gno-record-gcc-switches -fno-common"
</pre></details>

### What did you do?

The Go source code

```go
package gocode

import "fmt"

type Bytes struct {
	elements []byte
}

func NewBytes(elements []byte) *Bytes {
	fmt.Println("Constructor: ", elements)
	return &Bytes{elements: elements}
}

func (bytes *Bytes) GetElements() []byte {
	fmt.Println("Getter: ", bytes.elements)
	return bytes.elements
}
```

is compiled into an iOS framework using `$GOPATH/bin/gomobile bind -target ios -o Gocode.framework gocode`.
In a minimal iOS application there is the Swift code

```swift
import Foundation
import Gocode

let data = Data(repeating: 0, count: 8)
print("Data: \([UInt8](data))")
let bytes = GocodeNewBytes(data)!
print("Elements: \([UInt8](bytes.getElements()!))")
print("Data: \([UInt8](data))")
```

which can be compiled and run just fine. However, the printed values are not what I would expect. 

### What did you expect to see?

```
Data: [0, 0, 0, 0, 0, 0, 0, 0]
Constructor:  [0 0 0 0 0 0 0 0]
Getter:  [0 0 0 0 0 0 0 0]
Elements: [0, 0, 0, 0, 0, 0, 0, 0]
Data: [0, 0, 0, 0, 0, 0, 0, 0]
```

### What did you see instead?

```
Data: [0, 0, 0, 0, 0, 0, 0, 0]
Constructor:  [0 0 0 0 0 0 0 0]
Getter:  [184 144 247 1 1 0 0 0]
Elements: [184, 144, 247, 1, 1, 0, 0, 0]
Data: [0, 0, 0, 0, 0, 0, 0, 0]
```

The data is correctly passed to the Go functions and back to Swift, but internally constructing the `Bytes` object it somehow changes. If I rewrite the constructor in Go as

```go
func NewBytes(elements []byte) *Bytes {
	fmt.Println("Constructor: ", elements)
	tmp := make([]byte, len(elements))
	copy(tmp, elements)
	return &Bytes{elements: tmp}
}
```

it works as anticipated. I'm not sure whether this is a bug or expected but unpleasant behavior due to Go's and Swift's handling of values and references. If the latter is true I really have no idea how to solve this issue on the Swift side in order to utilize Go libraries using `[]byte` at any interface function.