Pointer arithmetic in Go - pointers

Considering you can (can't think of a great way to put it, but) manipulate pointers in Go, is it possible to perform pointer arithmetic like you would in C, say for iterating over an array? I know loops are just fine for that kind of things these days but I'm just curious if it's possible.

No. From the Go FAQ:
Why is there no pointer arithmetic?
Safety. Without pointer arithmetic it's possible to create a language that can never derive an illegal address that succeeds incorrectly. Compiler and hardware technology have advanced to the point where a loop using array indices can be as efficient as a loop using pointer arithmetic. Also, the lack of pointer arithmetic can simplify the implementation of the garbage collector.
That being said, you can get around this by using the unsafe package, but just don't:
package main
import "fmt"
import "unsafe"
func main() {
vals := []int{10, 20, 30, 40}
start := unsafe.Pointer(&vals[0])
size := unsafe.Sizeof(int(0))
for i := 0; i < len(vals); i++ {
item := *(*int)(unsafe.Pointer(uintptr(start) + size*uintptr(i)))
fmt.Println(item)
}
}
https://play.golang.org/p/QCHEQqy6Lg

As of Go 1.17, we now have unsafe.Add, which makes it a little easier:
package main
import (
"unsafe"
)
func main() {
vals := []int{10, 20, 30, 40}
ptrStart := unsafe.Pointer(&vals[0])
itemSize := unsafe.Sizeof(vals[0])
for i := 0; i < len(vals); i++ {
item := *(*int)(unsafe.Add(ptrStart, uintptr(i)*itemSize))
println(item)
}
}
Playground.

Related

Golang : convert Byte slice array to integer array

In Golang, the code [body, err := ioutil.ReadAll(resp.Body)], the ioutil.ReadAll() returns a byte Slice array, based on the documentation.
This is stored in the variable 'body'. My question is how to convert this byte Slice array, to an array of Integers.
I just found some code that does what I was wanting:
import "fmt"
import "strconv"
func main() {
var t = []string{"1", "2", "3"}
var t2 = []int{}
for _, i := range t {
j, err := strconv.Atoi(i)
if err != nil {
panic(err)
}
t2 = append(t2, j)
}
fmt.Println(t2)
}
So this code, does do what I want.
BUT l am disappointed in Golang, for not having a nice one liner that could do this
kind of conversion.
Certain basic things like this, should be packaged up for the programmer, and not have to do this kind of 'low' level programming.
Note, i still like Golang, they had done a lot to make a better C type language that has higher level Data Types when compared to C and also make some things more dynamic compared to C.
SO just disappointed they did not make a High Abstraction for this kind of case, which comes up quite a bit.

How do cleanly initialize two structs in golang which depend on each other?

I've run into an issue in my current project where I have two modules, one implementing an interface for testing purposes, and one just a concrete struct, which each depend on a method from the other.
In order to resolve this tension, I've attempted to create a top-level "container" struct that holds a reference to the dependent struct and interface, and then with a method on the container struct, assign as a member of each component struct that top level container's pointer to the other struct. I am doing this instead of using globals in order to be able to better encapsulate my code for testing purposes.
However, it seems that whichever struct is initialized first does not see the change in the other struct's address when the second struct is initialized. I do not understand why, and I don't seem to be able to make this function as expected.
Since there are many extraneous details in the actual code I've created this toy example to illustrate what I'm talking about.
type container struct {
r requestor
a *A
}
type requestor interface {
Request()
}
type A struct {
r requestor
}
type R struct {
a *A
}
func (r R) Request() {
log.Info("I requested")
return
}
func (container *container) NewA() *A {
log.Info("New A received container.r: ", container.r)
a := &A{
r: container.r,
}
container.a = a
return a
}
func (container *container) NewR() *R {
r := &R{
a: container.a,
}
container.r = r
return r
}
func TestDepResolution(t *testing.T) {
top := container{}
top.NewR()
top.NewA()
// top.a.r = r
log.Infof("top: %+v", top)
log.Infof("R: %+v", top.r)
log.Infof("A: %+v", top.a)
}
It's setup as a test so I can easily execute it within my project. The output is as such:
=== RUN TestDepResolution
INFO[0000] New A received container.r: <nil>
INFO[0000] top: {r:0xc000010028 a:0xc00006abc0}
INFO[0000] R: &{a:0xc00006abc0}
INFO[0000] A: &{r:<nil>}
I expected that A's r variable would become equal to top's r variable after NewR() was called, but it doesn't seem to change. The same issue occurs the other way around if I switch the order of NewA() and NewR().
I expected since I am using pointers and interfaces here that the values would be connected when top's values changed, but it's apparent I must be misunderstanding something. I've tried playing around with the pointers quite a bit to no avail.
So why doesn't this work as I expected? Is there a way to make this work as I've proposed? Or am I thinking about this issue in an entirely wrongheaded way? I have tried to think about extracting functionality from the modules so that they are not mutually dependent and I could avoid this issue entirely, but I have not been able to come up with a good way to do so.
To be able to utilize pointers the way you seem to want to, you first need actual pointers (i.e. not nil pointers) and you also need to use pointer indirection to be able to "share" the updates to the pointed values.
For example:
type T struct { F string }
a := &T{"foo"} // non-nil pointer
b := a
fmt.Println(b) // output: {"foo"}
*a = T{"bar"} // pointer indirection
fmt.Println(b) // output: {"bar"}
For comparison, here's what your code is attempting to do:
type T struct { F string }
a := (*T)(nil) // nil pointer
b := a
fmt.Println(b) // output: <nil>
a = &T{"bar"} // plain assignment
fmt.Println(b) // output: <nil>
And note that even if you used pointer indirection, it is illegal to do so on a nil pointer and the runtime, if it encounters such an operation, will panic.
a := (*T)(nil) // nil pointer
b := a
fmt.Println(b) // output: <nil>
*a = T{"bar"} // pointer indirection on nil, will crash the program
fmt.Println(b)
So, your example doesn't work because it does not properly initialize the pointers and it does not use pointer indirection, rather, it uses simple assignment which just updates the target variable's pointer and not the pointed-to value.
To initialize the container properly you should do it in one step:
func NewContainer() *container {
c := &container{a: &A{}}
c.r = &R{a: c.a}
c.a.r = c.r
return c
}
https://play.golang.com/p/hfbqJEVyAHZ
Or, if you want to do it in two, you can do something like this:
func (c *container) NewA() *A {
log.Println("New A received c.r: ", c.r)
a := &A{
r: c.r,
}
if c.a != nil {
*c.a = *a
} else {
c.a = a
}
return a
}
func (c *container) NewR() *R {
if c.a == nil {
c.a = new(A)
}
r := &R{
a: c.a,
}
c.r = r
c.a.r = r
return r
}
https://play.golang.com/p/krmUQOsACdU
but, as you can see, the multi step approach to initializing so tightly coupled dependencies can get unnecessarily convoluted and ugly, i.e. complex, i.e. very much error prone. Avoid it if you can.
All that said, personally, I would consider this kind of circular dependency a smell and would start thinking about redesign, but maybe that's just me.

Behavior of a pointer to an element of `slice` after the `slice` had been appended to

I am wondering what is the behavior of a pointer to an element of slice after the slice had been appended to, for example:
package main
import "fmt"
func main() {
my_slice := []int {3}
silly_ptr := &my_slice[0]
// Do we know that silly_ptr points to value equal 3
// all the time? (If we don't explicitly change it).
fmt.Printf("%p\n", silly_ptr)
fmt.Println(*silly_ptr)
for i := 0; i < 10; i++ {
my_slice = append(my_slice, i)
}
silly_ptr_2 := &my_slice[0]
fmt.Printf("%p\n", silly_ptr_2)
fmt.Println(*silly_ptr_2)
}
Produces: (no surprises)
0xc20800a200
3
0xc20805a000
3
I know that when appending to dynamic array, at certain points we have repopulate the entire array, and therefore memory address of the original array elements is not reliable. To the best of my knowledge similar code is valid in c++, but silly_ptr could be pointing to anything. rust does not allow mutating a vector if it is being borrowed, so the above logic would not compile.
But what about Go? I know that by escape analysis it is valid to return a pointer to a local variable, the variable would be just created on the heap for you. My intuition tells me that the same logic applies in the above case. The memory location where silly_ptr is pointing to will not be repopulated, and hence will always store 3 (if we don't explictly change it). Is this right?
No, it will not always store 3.
Go has memory management. As long as there is an active pointer to an underlying array for a slice, the underlying array is pinned, it will not be garbage collected. If you have a pointer to an element of an underlying array, you can change the value of the element. For example,
package main
import (
"fmt"
)
func pin() *int {
s := []int{3}
fmt.Println(&s[0])
a := &s[0]
s = append(s, 7)
fmt.Println(&s[0])
return a
}
func main() {
a := pin()
fmt.Println(a, *a)
*a = 42
fmt.Println(a, *a)
}
Output:
0xc82000a340
0xc82000a360
0xc82000a340 3
0xc82000a340 42
A slice descriptor contains a pointer to an underlying array so you can see something similar with a slice. For example,
package main
import (
"fmt"
)
func pin() []int {
s := []int{3}
fmt.Println(&s[0])
d := s
s = append(s, 7)
fmt.Println(&s[0])
return d
}
func main() {
d := pin()
fmt.Println(&d[0], d)
d[0] = 42
fmt.Println(&d[0], d)
}
Output:
0xc82000a340
0xc82000a360
0xc82000a340 [3]
0xc82000a340 [42]

What pointers may be used for in Go?

I think I understand what pointer is but I don't quite understand when to use it.
The below snippet is from "A Tour of Go".
What is the purpose of "*Vertex" and "&Vertex"?
I replaced them with "Vertex" and it run fine.
package main
import (
"fmt"
"math"
)
type Vertex struct {
X, Y float64
}
func (v *Vertex) Abs() float64 {
return math.Sqrt(v.X*v.X + v.Y*v.Y)
}
func main() {
v := &Vertex{3, 4}
fmt.Println(v.Abs())
}
That's not a particularly good example of the pointer/value distinction, because in that case they're interchangeable! Pointers are useful when you need to mutate data "remotely" (from another function).
func (v Vertex) SetX(x int) {
v.X = x
}
func main() {
v := Vertex{3, 4}
fmt.Println(v)
v.SetX(1)
fmt.Println(v)
}
As you'll note, this doesn't change anything (strictly speaking, it changes a copy of the vertex, but that's just semantics in most cases)! The value of v is still {3,4}. Trying instead with:
func (v *Vertex) SetX(x int) {
v.X = x
}
func main() {
v := &Vertex{3, 4}
fmt.Println(v)
v.SetX(1)
fmt.Println(v)
}
And suddenly, it works, the second time it prints {1,4}. Now, if you're curious, you may decide to experiment and change v := &Vertex{3, 4} to v := Vertex{3, 4}. Indeed, the above snippet still works. Strange. Likewise, if you change the same line in the second snippet to contain a pointer, it also works the same way.
Why? Go has "transparent" pointers. In other languages with explicit pointer values like C or C++, you have to explicitly use the operators & and * to dereference a pointer. C and C++ even have special syntax for pointer chasing on field access and method calls v->SetX.
For better or worse, Go hides this from you. If you have a value and need to call a pointer method, Go will happily do (&v).Method() for you, if you need to dereference to call a value method, it happily does (*v).Method() automatically. This is true in most cases, there are a few corner cases with things like maps where this doesn't apply, but in general this holds.
So, when it comes down to it, when should you use a pointer receiver on a method? The answer, really, is "most of the time." The Go Style Guide generally recommends using pointer type method receivers except when the receiver is a direct alias for a map, func, or chan, it's a slice that doesn't need reslicing, or you're doing optimizations on small, immutable data types (because pointer chasing is a little bit slower than copying). I'd add to that that you generally shouldn't use direct pointers to pointers.
Generally, when you have no idea which to use, use a pointer receiver. 99% of the time using a pointer will give you the behavior you expect, especially if you're used to languages like Python or C#. It's comparatively rare that incorrectly using a pointer causes a bug, compared the probability of getting a bug because your Setter method isn't actually setting anything.
This particular example is bad because the method defined on pointer type, *Vertex, does not attempt to mutate the value of its receiver (the value the method is called on).
In Go, everything is ever passed/assigned by value — including pointers. So, when you have a method
func (v Vertex) Abs() float64 {
return math.Sqrt(v.X*v.X + v.Y*v.Y)
}
(notice there's no * in front of Vertex in the receiver's type specification), it works just OK because when you do
v := Vertex{2, 3}
x := v.Abs()
the value of v at the v.Abs() call site is copied to the value the Abs() method receives.
Now suppose you want to change (mutate) some of the Vertex's variables using a method call. A naive approach, like in,
func (v Vertex) SetX(x float64) {
v.X = x
}
v := Vertex{2, 3}
v.SetX(-5)
// Here, v.X is still 2
won't work because it will change X of the value v which has been copied to the callee when the call was made; the method changed the X of the copy—a change only seen in the method's scope.
On the other hand, if you were to define that method on the pointer (which holds the address of an actual variable holding a value instead of the value itself), that would work:
func (v *Vertex) SetX(x float64) {
v.X = x
}
v := Vertex{2, 3}
v.SetX(-5)
Here, the compiler would take the address of v at the point SetX() is called and pass it to the method. The method would then use that address to refer to the value in the caller's scope.
The syntactic confusion is because Go (in most cases) allows you to not use operators to take address of a value and dereference that address.
If you're coming from one of popular languages like PHP, Python etc the chief difference is that in many of them objects are "special" and are always passed by reference. Go is more low-level and tries not to use magic behind programmer's back, so you have to be explicit about whether you want to pass a pointer or a copy of the value to a method.
Note that this is not only about whether a method is able or is not able to mutate its receiver; performance things might also play a role here.

Using a pointer to array

I'm having a little play with google's Go language, and I've run into something which is fairly basic in C but doesn't seem to be covered in the documentation I've seen so far
When I pass a pointer to a slice to a function, I presumed we'd have some way to access it as follows:
func conv(x []int, xlen int, h []int, hlen int, y *[]int)
for i := 0; i<xlen; i++ {
for j := 0; j<hlen; j++ {
*y[i+j] += x[i]*h[j]
}
}
}
But the Go compiler doesn't like this:
sean#spray:~/dev$ 8g broke.go
broke.go:8: invalid operation: y[i + j] (index of type *[]int)
Fair enough - it was just a guess. I have got a fairly straightforward workaround:
func conv(x []int, xlen int, h []int, hlen int, y_ *[]int) {
y := *y_
for i := 0; i<xlen; i++ {
for j := 0; j<hlen; j++ {
y[i+j] += x[i]*h[j]
}
}
}
But surely there's a better way. The annoying thing is that googling for info on Go isn't very useful as all sorts of C/C++/unrelated results appear for most search terms.
The Google Go docs state the following about passing arrays - they say you usually want to pass a slice (instead of a pointer?):
Updated:
As indicated by #Chickencha's comment, array slices are references which is why they are efficient for passing. Therefore likely you will want to use the slice mechanism instead of "raw" pointers.
From Google Effective Go doc http://golang.org/doc/effective_go.html#slices
Slices are reference types,
Original
It's under the heading
An Interlude about Types
[...snip...] When passing an array
to a function, you almost always want
to declare the formal parameter to be
a slice. When you call the function,
take the address of the array and Go
will create (efficiently) a slice
reference and pass that.
Editor's note: This is no longer the case
Using slices one can write this function (from sum.go):
09 func sum(a []int) int { // returns an int
10 s := 0
11 for i := 0; i < len(a); i++ {
12 s += a[i]
13 }
14 return s
15 }
and invoke it like this:
19 s := sum(&[3]int{1,2,3}) // a slice of the array is passed to sum
Maybe pass the whole array as a slice instead. Google indicates Go deals efficiently with slices. This is an alternate answer to the question but maybe it's a better way.
Types with empty [], such as []int are actually slices, not arrays. In Go, the size of an array is part of the type, so to actually have an array you would need to have something like [16]int, and the pointer to that would be *[16]int. So, what you are actually doing already is using slices, and the pointer to a slice, *[]int, is unnecessary as slices are already passed by reference.
Also remember that you can easily pass a slice referring to the entire array with &array (as long as the element type of the slice matches that of the array). (Not anymore.)
Example:
package main
import "fmt"
func sumPointerToArray(a *[8]int) (sum int) {
for _, value := range *a { sum += value }
return
}
func sumSlice (a []int) (sum int) {
for _, value := range a { sum += value }
return
}
func main() {
array := [...]int{ 1, 2, 3, 4, 5, 6, 7, 8 }
slice := []int{ 1, 2, 3, 4 }
fmt.Printf("sum arrray via pointer: %d\n", sumPointerToArray(&array))
fmt.Printf("sum slice: %d\n", sumSlice(slice))
slice = array[0:]
fmt.Printf("sum array as slice: %d\n", sumSlice(slice))
}
Edit: Updated to reflect changes in Go since this was first posted.
The semicolon and the asterisk are added and removed.
*y[i+j] += x[i]*h[j]
Is interpreted as
(*y)[i+j] += x[i] * h[j];
EDIT: Please read the comments. The answer is probably no longer valid. and I haven't touched up on go for quite some time and can't even read this anymore.
The length is part of the array's type, you can get length of an array by the len() built-in function. So you needn't pass the xlen, hlen arguments.
In Go, you can almost always use slice when passing array to a function. In this case, you don't need pointers.
Actually, you need not pass the y argument. It's the C's way to output array.
In Go style:
func conv(x, h []int) []int {
y := make([]int, len(x)+len(h))
for i, v := range x {
for j, u := range h {
y[i+j] = v * u
}
}
return y
}
Call the function:
conv(x[0:], h[0:])
Here's a working Go program.
package main
import "fmt"
func conv(x, h []int) []int {
y := make([]int, len(x)+len(h)-1)
for i := 0; i < len(x); i++ {
for j := 0; j < len(h); j++ {
y[i+j] += x[i] * h[j]
}
}
return y
}
func main() {
x := []int{1, 2}
h := []int{7, 8, 9}
y := conv(x, h)
fmt.Println(len(y), y)
}
To avoid wrong guesses, read the Go documentation: The Go Programming Language.
Almost all the other answers to this question talk about using slices instead of
array pointers but none answers how to solve the error, so I thought I would
write this answer. The error gives us a hint that it cannot access the index of
y because it is an invalid operation.
Your first approach is wrong as the Go compiler shouts at you. The problem in
the first approach is that *y[i+j] is wrong syntax. This is because
technically you are doing this *(y[i+j]) and you can't just do that because
y in your case is a pointer to an int array. If you print y it would print
the memory address of the array.
You are trying to get the i+jth index of y which does not simply exist
because y is not an array. You can fix your code by adding parentheses to the
statement which would indicate that you are trying to get the i+jth index of
the array that y is pointing to. Use (*y)[i+j] instead of *y[i+j]. The
function would look like this after making the changes:
func conv(x []int, xlen int, h []int, hlen int, y *[]int) {
for i := 0; i<xlen; i++ {
for j := 0; j<hlen; j++ {
(*y)[i+j] += x[i]*h[j]
}
}
}

Resources