Get pointer on var obtained via interface - pointers

In the following code
var a int
var b interface{}
b = a
fmt.Printf("%T, %T \n", a, &a)
fmt.Printf("%T, %T \n", b, &b)
output:
int, *int
int, *interface {}
I would expect the type of &b to be a pointer on int.
I have two questions:
1) Why is it a pointer on interface{} ?
2) How could I get a pointer on the original type ?

&b => this is the address operator applied on the variable b, whose type is interface{}. So &b will be a pointer of type *interface{}, pointing to the variable b. If you take the address of a variable of type T, the result will always be of type *T.
You cannot obtain the address of the variable a from b, because the assignment:
b = a
Simply copies the value of a into b. It wraps the value of a in an interface value of type interface{}, and stores this interface value into b. This value is completely detached from a.
In general, all assignments copy the values being assigned. There are no reference types in Go. The closest you can get to what you want is if you store the address of a in b in the first place, e.g.:
b = &a
Then you can use type assertion to get out a's address from b like this:
fmt.Printf("%T, %T \n", a, &a)
fmt.Printf("%T, %T \n", b, b.(*int))
This outputs (try it on the Go Playground):
int, *int
*int, *int
(Note: when you simply print b, since it is of an interface type, the fmt package prints the (concrete) value wrapped in it.)
See related questions:
How to get a pointer to a variable that's masked as an interface?
Changing pointer type and value under interface with reflection

Just to complete icza's answer. In case if you don't know the type of the value stored in the interface (and, hence, you can't explicitly use type assertion), you can use reflect package:
var a int
var b interface{}
b = &a
fmt.Println(reflect.TypeOf(b))

Related

Why is it not possible to add an integer to a "dereferenced" pointer variable in Go?

Coming from Python, I'm currently learning Go and trying to wrap my head around pointers.
I've written this code in order to understand the concept:
a := 1
b := &a
fmt.Println(b) // Shows the memory address of a
fmt.Println(*b) // Shows the value 1
*b++
fmt.Println(a) // Shows the value 2 (as expected)
I tried to play around with this code to improve my understanding. The following, however, does not work:
a := 1
b := &a
fmt.Println(b) // Shows the memory address of a
fmt.Println(*b) // Shows the value 1
b = *b + 1 // Compile error: invalid operation: b * +1 (mismatched types *int and int)
fmt.Println(a)
Apparently, *b is of type *int, while the value 1 is (obviously) of type int. However, why is it possible to increment the value of a with *b++in the first example?
From the beginning:
b := &a
Here, b is of type *int, a pointer to a location in memory where value of a is stored. When you do *b, you are accessing a value from the location b pointer points to.
When you do *b++, it stands for *b = *b + 1 and you are incrementing a value on the location b pointer points to.
b = *b + 1 is invalid because you are trying to add *b and 1, which are both type of int, to b, which is a pointer (type of *int).
Why is it not possible to add an integer to a “dereferenced” pointer variable in Go?
b is a pointer and dereferenced b is written as *b. b = *b + 1 is invalid because you're trying to convert an integer to a pointer, which is not possible even when explicitly typecasted. You'll need to instead modify the data that pointer is pointing to, not the pointer itself: *b = *b + 1.
Take a look at the Go spec here regarding why *b++ works: https://golang.org/ref/spec
Operator precedence
Unary operators have the highest precedence. As the ++ and -- operators form statements, not expressions, they fall outside the operator hierarchy. As a consequence, statement *p++ is the same as (*p)++.
Adding an integer to a dereferenced (integer) pointer variable is possible and is working in your case correctly. However, assigning this value to a pointer variable is not acceptable in Go for type safety reasons. And it is normally not needed (but there is a way to reference any given address though). Hope this clarifies it.
You are adding a *int to an int. Hence, the error.
As b is a pointer to an integer, to do anything with that integer(read or write), you need to de-reference it. Below code will work as expected. That's what *b++ does internally.
package main
import (
"fmt"
)
func main() {
a := 1
b := &a
fmt.Println(b) // Shows the memory address of a
fmt.Println(*b) // Shows the value 1
*b = *b + 1 // No Compile error
fmt.Println(a) // Shows the value 2
}
Try it here:
https://play.golang.org/p/2RX1CWD-AQC

How to print dereferenced value of field without explicitly specifying that field golang

package main
import (
"fmt"
)
type outer struct {
in *int
}
func main() {
i := 4
o := outer{&i}
fmt.Printf("%+v", o)
}
I'd like to see {in:4} at the end of this, not {in:0x......}, i.e. pretty print the data structure.
I'd like to accomplish this in a similar manner to the code posted (e.g. with a fmt shortcut similar to %+v or an analogous solution).
This is for autogenerated code from a required field of a thrift struct.
What's the best way to go about this?
When you use &i it does not dereference i. Rather it references i, which means that it copies the address of i into o. See the documentation for the Address operators.
From what I gather, you should be able to use *o to dereference the pointer; in other words, go from the address back to the original variable.
For an operand x of pointer type *T, the pointer indirection *x denotes the variable of type T pointed to by x. If x is nil, an attempt to evaluate *x will cause a run-time panic.

reflect.New returns <nil> instead of initialized struct

I am using reflection for a library I'm building but there's something I don't understand about reflect.New.
type A struct {
A int
B string
}
func main() {
real := new(A)
reflected := reflect.New(reflect.TypeOf(real)).Elem().Interface()
fmt.Println(real)
fmt.Println(reflected)
}
Gives:
$ go run *go
&{0 }
<nil>
Isn't reflect.New supposed to return &{0 } too? (Runnable Version)
Ultimately, I wish to be able to iterate over the fields of the reflected struct (reflected.NumField() gives reflected.NumField undefined (type interface {} is interface with no methods)) and use SetInt, SetString and so on.
Thanks,
You used the builtin new() function when you created your real variable, which returns a pointer! Type of real is *A, not A! This is the source of the confusion.
reflect.New() returns a pointer to the (zeroed) value of the given type (wrapped in a reflect.Value). If you pass the type A, you get back a wrapped *A, A initialized / zeroed. If you pass the type *A, you get back a wrapped **A, *A initialized (zeroed), and the zero value for any pointer type is nil.
You basically ask reflect.New() to create a new value of a pointer type (*A), and –as mentioned– its zero value is nil.
You have to pass the type A (and not the type *A). It works like this (try it on the Go Playground):
real := new(A)
reflected := reflect.New(reflect.TypeOf(real).Elem()).Elem().Interface()
fmt.Println(real)
fmt.Println(reflected)
Or like this (Go Playground):
real := A{}
reflected := reflect.New(reflect.TypeOf(real)).Elem().Interface()
fmt.Println(real)
fmt.Println(reflected)

Confused with implicit pointer dereference when assigning a pointer to interface in Go

I am new to Go, and I am studying its interface feature.
Here is the code:
package main
import (
"fmt"
"reflect"
)
type Integer int
func (a Integer) Less(b Integer) bool {
return a < b
}
func (a *Integer) Add(b Integer) {
*a += b
}
type LessAdder interface {
Less(b Integer) bool
Add(b Integer)
}
var a Integer = 1
var b LessAdder = &a
func main() {
fmt.Println(reflect.TypeOf(b))
fmt.Println(b.Less(2))
b.Add(a)
fmt.Println(a)
}
And it will output the the following:
*main.Integer
true
2
Well, this works pretty well.
The Point is:
How var b LessAdder = &a works. Does the pointer auto-dereference happens right here, or when b invokes member method?
The output *main.Integer tells us that b is a pointer to type Integer, hence it is the second case.
Then the tricky thing comes:
when I add fmt.Pringln(*b) to the code, the compiler comes with an error:
demo/demo1
./demo1.go:31: invalid indirect of b (type LessAdder)
And it confuses me. Since b is a pointer type to Integer, then dereferencing it should work. But why not?
Your last sentence:
"Since b is a pointer type to Integer, then dereferencing it should work."
Stop right there. b is not a variable of pointer type and therefore you can't dereference it.
It is a variable of interface type which is schematically a pair of a value and a type (value,type), holding &a as the value and *Integer as the type (blog article The Laws of Reflection, section The representation of an interface).
This is a declaration of a variable of pointer type, *Integer:
var ip *Integer
And this is one of an interface type:
var intf LessAdder
When you do this:
var b LessAdder = &a
What happens is that an interface value (of type LessAdder) is created automatically/implicitly which will hold the value &a (and the type *Integer). This is a valid operation because the type of &a (which is *Integer) implements the interface LessAdder: the method set of *Integer is a superset of the interface LessAdder (in this case they are equal, the method set of an interface type is its interface).
Now when you call b.Less(2), since Less() has a value receiver, the pointer will be dereferenced and a copy of the pointed value will be made and used/passed as the value receiver of the method Less().
fmt.Println(reflect.TypeOf(b)) doesn't lie, but it will print the dynamic type of b. The dynamic type of b is indeed *Integer, but the static type of b is LessAdder and the static type is what determines what you can do with a value and what operators or methods are allowed on it.
LessAdder is declared as an interface with the methods Less and Add. Since Add is declared with a receiver of *Integer, a *Integer can be a LessAdder; an Integer can't. When you do var b LessAdder = &a, it's the pointer to a that's stored in the interface b.
The automatic indirection occurs at the call to b.Less(2), because both methods on *Integer and methods on Integer contribute to the method set of *Integer.
You can't use *b because although b contains a *Integer, statically its type is LessAdder, not *Integer. Leaving aside the representation of interfaces, LessAdder isn't a pointer type, and *b, if it was allowed, would have no expressible type at all.
You can use a type assertion to access b as an Integer * again; b.(*Integer) is an expression of type *Integer, and *b.(*Integer) is an Integer. Both of these will run-time panic if the value in b is not a *Integer after all.

How to print out pointer variable correctly in golang

type person struct{}
var tom *person = &person{}
When I use
fmt.Printf("%+v\n", tom)//prints:&{}
Why the result is & plus data?It is surposed to be an address(0x0055)
When I use
fmt.Printf("%+v\n", &tom)//0x0038
fmt.Printf("%p\n", &tom)//0x0038
It gives me an address,it gives me 0x0038,why %v and %p has the same result?
tom is a pointer to a person. When you use &tom, you're a creating a second pointer, this a pointer to a pointer to a person.
In your first example, you're using %+v to print the default value of tom. The default value deferences the pointer and prints the struct itself.
In your second example, %+v is applying to the "double" pointer. It still deferences the pointer, getting to the initial pointer. See this example: http://play.golang.org/p/IZThhkiQXM

Resources