How to print out pointer variable correctly in golang - pointers

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

Related

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)

Pointers golang from string

My application accepts a pointer from os.Args.
For example
pointer := os.Args[1] //"0x7ffc47e43200"
How can I use that pointer and get the value that is stored on that location?
Disclaimer: As you are probably aware, this is dangerous and if you're going to do this in a production application, you'd better have a really good reason. That being said...
You need to do a few things. Here's the code, and then we'll walk through it.
package main
import (
"fmt"
"os"
"strconv"
"unsafe"
)
func main() {
str := "7ffc47e43200" // strconv.ParseUint doesn't like a "0x" prefix
u, err := strconv.ParseUint(str, 16, 64)
if err != nil {
fmt.Fprintln(os.Stderr, "could not parse pointer:", err)
os.Exit(1)
}
ptr := unsafe.Pointer(uintptr(u)) // generic pointer (like void* in C)
intptr := (*int)(ptr) // typed pointer to int
fmt.Println(*intptr)
}
You can run this on the Go Playground.
First, we need to parse the string as a numerical value. In your example, you gave a hexadecimal number, so we'll parse in base 16 (that's the "16" argument to strconv.ParseUint). Note that strconv.ParseUint doesn't like the "0x" prefix, so I removed it.
Then, we need to convert the number into a pointer type. For this, we will use the unsafe.Pointer type, which is special to the Go compiler. Normally, the compiler won't let you convert between pointer types. The exception is that, according to the unsafe.Pointer documentation:
A pointer value of any type can be converted to a Pointer.
A Pointer can be converted to a pointer value of any type.
A uintptr can be converted to a Pointer.
A Pointer can be converted to a uintptr.
Thus, in order to convert to a pointer, we'll need to first convert to a uintptr and then to an unsafe.Pointer. From here, we can convert to any pointer type we want. In this example, we will convert to an int pointer, but we could choose any other pointer type as well. We then dereference the pointer (which panics in this case).

Pointer to a struct (or lack thereof)

Let's say I have defined this struct:
type Vertex struct {
X, Y float64
}
now it's perfectly legal Go to use it like this:
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())
}
but it's also ok not to use a pointer:
func main() {
v := Vertex{3, 4}
fmt.Println(v.Abs())
}
The results in both cases is the same, but how are they different, internally? Does the use of pointer makes the program run faster?
PS. I get it that the Abs() function needs a pointer as a receiver. That explains the reason why a pointer has been used later in the main function. But why doesn't the program spit out an error when I don't use a pointer and directly call Abs() on a struct instance?
why doesn't the program spit out an error when I don't use a pointer and directly call Abs() on a struct instance?
Because you can get the pointer to (address of) a struct instance.
As mentioned in "What do the terms pointer receiver and value receiver mean in Golang?"
Go will auto address and auto-dereference pointers (in most cases) so m := MyStruct{}; m.DoOtherStuff() still works since Go automatically does (&m).DoOtherStuff() for you.
As illustrated by "Don't Get Bitten by Pointer vs Non-Pointer Method Receivers in Golang" or "Go 101: Methods on Pointers vs. Values", using a pointer receiver (v *Vertex) is great to avoid copy, since Go passes everything by value.
The spec mentions (Method values):
As with method calls, a reference to a non-interface method with a pointer receiver using an addressable value will automatically take the address of that value: t.Mp is equivalent to (&t).Mp.

Cast a struct pointer to interface pointer in Golang

I have a function
func doStuff(inout *interface{}) {
...
}
the purpose of this function is to be able to treat a pointer of any type as input.
But when I want to call it with a the pointer of a struct I have an error.
type MyStruct struct {
f1 int
}
When calling doStuff
ms := MyStruct{1}
doStuff(&ms)
I have
test.go:38: cannot use &ms (type *MyStruct) as type **interface {} in argument to doStuff
How can I cast &ms to be compatible with *interface{}?
There is no such thing as a "pointer to an interface" (technically, you can use one, but generally you don't need it).
As seen in "what is the meaning of interface{} in golang?", interface is a container with two words of data:
one word is used to point to a method table for the value’s underlying type,
and the other word is used to point to the actual data being held by that value.
So remove the pointer, and doStuff will work just fine: the interface data will be &ms, your pointer:
func doStuff(inout interface{}) {
...
}
See this example:
ms := MyStruct{1}
doStuff(&ms)
fmt.Printf("Hello, playground: %v\n", ms)
Output:
Hello, playground: {1}
As newacct mentions in the comments:
Passing the pointer to the interface directly works because if MyStruct conforms to a protocol, then *MyStruct also conforms to the protocol (since a type's method set is included in its pointer type's method set).
In this case, the interface is the empty interface, so it accepts all types anyway, but still.

Resources