If resp is a pointer to a response object, why don't we have to use resp* to access its value? - pointers

I recently began studying Golang and the accompanying documentation. In the Golang net/http documentation , the Get method is:
func Get(url string) (resp *Response, err error)
It is my understanding that this method returns a pointer to a response object or an error object (should an error occur). If resp is a pointer to a response object, why can the respvalue be accessed using the following code:
func main() {
resp, err := http.Get("http://google.com")
if err != nil {
fmt.Println("Error:", err)
os.Exit(1)
}
fmt.Println(resp)
}
Should it not be fmt.Println(*resp) instead? There are many other examples like this throughout the documentation. I thought I understood pointers but I am obviously missing something. Any help in clarifying this would certainly be appreciated.

If resp is a pointer to a response object, why can the [object itself] be accessed using [fmt.Println(resp)] ... Should it not be fmt.Println(*resp) instead?
If you send to fmt.Println a pointer to an object, fmt.Println can use the pointer to reach the object itself (i.e., access it—and even modify it, but fmt.Println doesn't modify it).
If you send to fmt.Println a copy of the object, fmt.Println can use the copy of the object, i.e., access it (and cannot modify the original).
So in that sense, giving fmt.Println the pointer value is strictly more powerful than passing a copy of the object, because it can modify the object. The fmt code does not use this power, but it's there in any other place that you might pass the pointer too. But as long as fmt.Println:
notices that this is a pointer, and then
follows the pointer to access the underlying object,
then fmt.Println can behave the same way on both pointer-to-object and copy-of-object.
In fact, the fmt.Print* family of functions do not quite behave the same way with pointer-to-object and copy-of-object:
package main
import (
"fmt"
)
type T struct {
Name string
Value int
}
func main() {
obj := T{Name: "bob", Value: 42}
fmt.Println(&obj, obj)
fmt.Printf("%#v %#v\n", &obj, obj)
}
When this is run (try it on the Go Playground), it prints:
&{bob 42} {bob 42}
&main.T{Name:"bob", Value:42} main.T{Name:"bob", Value:42}
That is, the default formatting, which you get with %v or fmt.Println, prints either:
{bob 42}
(copy of object) or:
&{bob 42}
(pointer to object). The alternative format obtained with %#v adds the type, so that you either get:
main.T{Name:"bob", Value:42}
(copy of object) or:
&main.T{Name:"bob", Value:42}
What we see here is that fmt.Println, which takes an interface{} value, goes through the following process:
Inspect the type of the value. Is it a pointer? If so, remember that it was a pointer. Print <nil> and do not go any further if it's a nil pointer; otherwise, obtain the object to which the pointer points.
Now that it's not a pointer: What type does the value have? If it's a struct type, print out its type name (%#v) or not (%v), prefixed with & if step 1 followed a pointer, and then the open brace and a list of the values of things inside the struct, and then a close brace to end the whole thing.
When using %#v, print the names of the fields and print the values in a format suitable for use as Go source code. Otherwise, just print the contents of strings and ints and so on.
Other pointer types do not always get the same treatment! For instance, add a int variable, set it to some value, and call fmt.Println(&i, i). Note that this time you don't get &42 42 or something like that, but rather 0x40e050 42 or something like that. Try this with fmt.Printf and %#v. So the output depends on the type and the formatting verb.
If you call functions that must modify their objects (such as the scan family in fmt), you must pass a pointer, since they need to have access to the objects to modify them.
Every function that can take values of unconstrained interface{} types (including everything in the Print* and Scan* family here) must document what they do with each actual type. If they say, as the Print* family do, that when given a pointer to a struct type, they follow the pointer (if not nil), that lets you know that you can send the pointer instead of the object.
(Some functions in some libraries are guilty of under-documenting what they do, and you have to experiment. This is not a great situation in general because the results of the experiment might be an accident of the current implementation, rather than a promised behavior that won't change in the future. This is one reason to be chary of using interface{}: it means you have to write a lot of documentation.)

Related

Custom errors in golang and pointer receivers

Reading about value receivers vs pointer receivers across the web and stackoverflow, I understand the basic rule to be: If you don't plan to modify the receiver, and the receiver is relatively small, there is no need for pointers.
Then, reading about implementing the error interface (eg. https://blog.golang.org/error-handling-and-go), I see that examples of the Error() function all use pointer receiver.
Yet, we are not modifying the receiver, and the struct is very small.
I feel like the code is much nicer without pointers (return &appError{} vs return appError{}).
Is there a reason why the examples are using pointers?
First, the blog post you linked and took your example from, appError is not an error. It's a wrapper that carries an error value and other related info used by the implementation of the examples, they are not exposed, and not appError nor *appError is ever used as an error value.
So the example you quoted has nothing to do with your actual question. But to answer the question in title:
In general, consistency may be the reason. If a type has many methods and some need pointer receiver (e.g. because they modify the value), often it's useful to declare all methods with pointer receiver, so there's no confusion about the method sets of the type and the pointer type.
Answering regarding error implementations: when you use a struct value to implement an error value, it's dangerous to use a non-pointer to implement the error interface. Why is it so?
Because error is an interface. And interface values are comparable. And they are compared by comparing the values they wrap. And you get different comparison result based what values / types are wrapped inside them! Because if you store pointers in them, the error values will be equal if they store the same pointer. And if you store non-pointers (structs) in them, they are equal if the struct values are equal.
To elaborate on this and show an example:
The standard library has an errors package. You can create error values from string values using the errors.New() function. If you look at its implementation (errors/errors.go), it's simple:
// Package errors implements functions to manipulate errors.
package errors
// New returns an error that formats as the given text.
func New(text string) error {
return &errorString{text}
}
// errorString is a trivial implementation of error.
type errorString struct {
s string
}
func (e *errorString) Error() string {
return e.s
}
The implementation returns a pointer to a very simple struct value. This is so that if you create 2 error values with the same string value, they won't be equal:
e1 := errors.New("hey")
e2 := errors.New("hey")
fmt.Println(e1, e2, e1 == e2)
Output:
hey hey false
This is intentional.
Now if you would return a non-pointer:
func New(text string) error {
return errorString{text}
}
type errorString struct {
s string
}
func (e errorString) Error() string {
return e.s
}
2 error values with the same string would be equal:
e1 = New("hey")
e2 = New("hey")
fmt.Println(e1, e2, e1 == e2)
Output:
hey hey true
Try the examples on the Go Playground.
A shining example why this is important: Look at the error value stored in the variable io.EOF:
var EOF = errors.New("EOF")
It is expected that io.Reader implementations return this specific error value to signal end of input. So you can peacefully compare the error returned by Reader.Read() to io.EOF to tell if end of input is reached. You can be sure that if they occasionally return custom errors, they will never be equal to io.EOF, this is what errors.New() guarantees (because it returns a pointer to an unexported struct value).
Errors in go only satisfy the error interface, i.e. provide a .Error() method. Creating custom errors, or digging through Go source code, you will find errors to be much more behind the scenes. If a struct is being populated in your application, to avoid making copies in memory it is more efficient to pass it as a pointer. Furthermore, as illustrated in The Go Programming Language book:
The fmt.Errorf function formats an error message using fmt.Sprintf and returns a new error value. We use it to build descriptive errors by successively prefixing additional context information to the original error message. When the error is ultimately handled by the program’s main function, it should provide a clear causal chain from the root problem to the overall failure, reminiscent of a NASA accident investigation:
genesis: crashed: no parachute: G-switch failed: bad relay orientation
Because error messages are frequently chained together, message strings should not be capitalized and newlines should be avoided. The resulting errors may be long, but they will be self-contained when found by tools like grep.
From this we can see that if a single 'error type' holds a wealth of information, and on top of this we are 'chaining' them together to create a detailed message, using pointers will be the best way to achieve this.
We can look at this from the error handling's perspective, instead of the error creation.
Error Definiton Side's Story
type ErrType1 struct {}
func (e *ErrType1) Error() string {
return "ErrType1"
}
type ErrType2 struct {}
func (e ErrType2) Error() string {
return "ErrType1"
}
Error Handler Side's Story
err := someFunc()
switch err.(type) {
case *ErrType1
...
case ErrType2, *ErrType2
...
default
...
}
As you can see, if you implements a error type on a value receiver, then when you are doing the type assertion, you need to worry about both cases.
For ErrType2, both &ErrType2{} and ErrType2{} satisfy the interface.
Because someFunc returns an error interface, you never know if it returns a struct value or a struct pointer, especially when someFunc isn't written by you.
Therefore, by using a pointer receiver doesn't stop a user from returning a pointer as an error.
That been said, all other aspects such as
Stack vs. Heap (memory allocation, GC pressure) still apply.
Choose your implementation according to your use cases.
In general, I prefer to a pointer receiver for the reason I demonstrated above. I prefer to Friendly API over performance and sometimes, when error type contains huge information, it's more performant.
No :)
https://blog.golang.org/error-handling-and-go#TOC_2.
Go interfaces allow for anything that complies with the error interface to be handled by code expecting error
type error interface {
Error() string
}
Like you mentioned, If you don't plan to modify state there is little incentive to pass around pointers:
allocating to heap
GC pressure
Mutable state and concurrency, etc
On a random rant , Anecdotally, I personally think that seeing examples like this one are why new go programers favor pointer receivers by default.
The tour of go explains the general reasons for pointer receivers pretty well:
https://tour.golang.org/methods/8
There are two reasons to use a pointer receiver.
The first is so that the method can modify the value that its receiver points to.
In general, all methods on a given type should have either value or pointer receivers, but not a mixture of both.

Pointers sent to function

I have following code in main():
msgs, err := ch.Consume(
q.Name, // queue
//..
)
cache := ttlru.New(100, ttlru.WithTTL(5 * time.Minute)) //Cache type
//log.Println(reflect.TypeOf(msgs)) 'chan amqp.Delivery'
go func() {
//here I use `cache` and `msgs` as closures. And it works fine.
}
I decided to create separate function for instead of anonymous.
I declared it as func hitCache(cache *ttlru.Cache, msgs *chan amqp.Delivery) {
I get compile exception:
./go_server.go:61: cannot use cache (type ttlru.Cache) as type *ttlru.Cache in argument to hitCache:
*ttlru.Cache is pointer to interface, not interface
./go_server.go:61: cannot use msgs (type <-chan amqp.Delivery) as type *chan amqp.Delivery in argument to hitCache
Question: How should I pass msg and cache into the new function?
Well, if the receiving variable or a function parameter expects a value
of type *T — that is, "a pointer to T",
and you have a variable of type T, to get a pointer to it,
you have to get the address of that variable.
That's because "a pointer" is a value holding an address.
The address-taking operator in Go is &, so you need something like
hitCache(&cache, &msgs)
But note that some types have so-called "reference semantics".
That is, values of them keep references to some "hidden" data structure.
That means when you copy such values, you're copying references which all reference the same data structure.
In Go, the built-in types maps, slices and channels have reference semantics,
and hence you almost never need to pass around pointers to the values of such types (well, sometimes it can be useful but not now).
Interfaces can be thought of to have reference semantics, too (let's not for now digress into discussing this) because each value of any interface type contains two pointers.
So, in your case it's better to merely not declare the formal parameters of your function as pointers — declare them as "plain" types and be done with it.
All in all, you should definitely complete some basic resource on Go which explains these basic matters in more detail and more extensively.
You're using pointers in the function signature but not passing pointers - which is fine; as noted in the comments, there is no reason to use pointers for interface or channel values. Just change the function signature to:
hitCache(cache ttlru.Cache, msgs chan amqp.Delivery)
And it should work fine.
Pointers to interfaces are nearly never used. You may simplify things and use interfaces of pass by value.

Why can't I use a pointer to a specific type where *interface{} is expected?

I have the following function:
func bytesToData(data interface{}, b []byte) error {
buf := bytes.NewBuffer(b)
dec := gob.NewDecoder(buf)
return dec.Decode(data)
}
I use this for getting struct data in and out of boltdb. What I'd like to do, is change that signature to:
func bytesToData(data *interface{}, b []byte) error
And then I'd like to be able to call it like this (b in this case is a gob-encoded Account)
acc := &Account{}
err := bytesToData(acc, b)
But when I do that, I get an error like Cannot use *Account for type *interface{}.
For now, I've just changed it back to interface{}. But then, if I pass in an Account or some other type directly without making it a pointer, gob throws an error. It seems like this should be checkable at compile time. And given that an argument of type interface{} accepts anything, why doesn't an argument of type *interface{} accept a pointer to anything?
The genericity of interface types in Go is not passed on to derived types. This applies to pointers (as you noticed), and also to slices, channels, etc. For example, you can't assign a []string to a []interface{}.
There are various ways to explain this. For a Haskell programmer:
Go does not have covariant or contravariant types. All type constructors (such as the * that creates a pointer type) are invariant. So even though Account and *Account (and all other types) are subtypes of interface{}, nothing is a subtype of *interface{} or []interface{}. This is sometimes inconvenient, but it keeps Go's type system and assignability rules much simpler.
For a C programmer:
An interface{} can hold a value of any type, but it does not hold it directly. Rather than being a variable-sized magic container, it is just a struct consisting of a pointer to a type and a pointer to a value. When you assign a concrete type to an interface{}, both of these fields are filled in. *interface{} is a pointer to one of these structs. When you try to assign a *Account to a *interface{}, there is nowhere to put the type information, because the *interface{} is a single machine word that just holds a pointer. So the compiler won't let you do that.
interface{} could also contain a pointer with no problem.
But there is nothing like a pointer to interface{}
See these:
Cast a struct pointer to interface pointer in Golang
Why can't I assign a *Struct to an *Interface?

Convert interface{} to *[]int in golang

I receive an interface which is basically a slice. Now I want to convert it to a pointer to the slice. The problem is, that I have either the slice itself or a Pointer to an interface.
I can easily show in a code example:
func main(){
model := []int{1,2,3,4,5,6,7,8,10,11,133123123123}
method(model)
}
func method(model interface{}){
fmt.Println(reflect.TypeOf(model)) // this is of type []int
fmt.Println(reflect.TypeOf(&model)) // this is of type *interface{}
}
What I need is this type:
fmt.Println(reflect.TypeOf(result)) // this should be type *[]int
I know the type only on runtime, therefore I cannot just take
&(model.([]int))
Is there a way using golang reflection to receive this? the type 'int' is here actually not important, important is, that it is a Pointer to a slice. *[]interface{} would be okay either.
Edit:
To make the question more clear, I should have added: I am not interested in the data of the slice, but only in getting a pointer to a slice of same type (which can basically be empty). Therefore James Henstridge answers works perfectly.
Before trying to answer the question, it is worth stepping back and asking what the *[]int value you're after should point at?
Given the way method is called we can't possibly get a pointer to the model variable from the calling context, since it will only receive a copy of the slice as its argument (note that this is a copy of the slice header: the backing array is shared).
We also can't get a pointer to the copy passed as an argument since it is stored as an interface{} variable: the interface variable owns the memory used to store its dynamic value, and is free to reuse it when the a new value is assigned to it. If you could take a pointer to the dynamic value, this would break type safety if a different type is assigned.
We can obtain a *[]int pointer if we make a third copy of the slice, but it isn't clear whether that's what you'd necessarily want either:
v := reflect.New(reflect.TypeOf(model))
v.Elem().Set(reflect.ValueOf(model))
result := v.Interface()
This is essentially a type agnostic way of writing the following:
v := new([]int)
*v = model
var result interface{} = v
Now if you really wanted a pointer to the slice variable in the calling context, you will need to ensure that method is called with a pointer to the slice instead and act accordingly.

go: using pointer allows changing the contents of a struct. Why?

Consider the following example. I don't fully understand what happens "in the background" and seek an explanation. This version seems to make a copy of the struct Foo when I call AddToEntry from the main function. Right? How can I "proof" this in the code?
When go makes a copy of the struct, I am just manipulating the copy of the struct and when I get back to the main function I see the original as before?
When I expect a pointer (see comment in the code), everything is fine, my struct is not copied. How can avoid this kind of "error"? How can I make sure I am not copying the struct? Is there a possible compile time/run time check for that, or do I have be careful?
package main
import (
"fmt"
)
type Foo struct {
Entry []string
}
func MakeFoo() Foo {
a:=Foo{}
a.Entry = append(a.Entry,"first")
return a
}
// if I change (f Foo) to (f *Foo), I get
// the "desired" result
func (f Foo) AddToEntry() {
f.Entry = append(f.Entry,"second")
}
func main() {
f:=MakeFoo()
fmt.Println(f) // {[first]}
f.AddToEntry()
fmt.Println(f) // {[first]}
}
Your method signature is func (f Foo) AddToEntry(). The way methods work, f.AddToEntry() is is the same as:
g := Foo.AddToEntry
g(f)
The receiver is just another parameter. Why is this important? What happens when you pass a struct and modify it in a function? In C, Go, and other pass by value languages, the struct given in the parameter is only a copy. Therefore, you can not modify the original. Only return the new struct.
When you define func (f *Foo) AddToEntry(), you are defining the receiver, the first parameter, as a pointer. Obviously, given a pointer, you can modify the original struct. What is hidden is that you are implicitly referencing when you access a struct in Go. To put it another way, (*ptrFoo).Entry is the same as ptrFoo.Entry in Go.
So the issue here is that for those unaccustomed to go, the syntax is hiding some of what is going on. In C, you would never be able to edit a struct unless you passed a pointer to it. The same happens in Go. You need to use a pointer receiver in order to modify what you are receiving.
Have you read this Go documentation?
Should I define methods on values or pointers?
Methods: Pointers vs. Values
The Go Programming Language Specification
How can I make sure I am not copying the struct? Is there a possible
compile time/run time check for that, or do I have be careful?
The short answer here is that no , you can't do a compile-time or run-time(1) check
for this - you just have to be careful. Once you get a bit familiar with go, this becomes natural.
(1)
Technically your function could query whether the type is a pointer or not with the type switch, but if you remember to do that, you'll also remember to make the parameter a pointer.

Resources