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.
Related
Is there a reason why Go standard library prefers pointer receivers, even where value receivers would work?
For example, in go 1.14 io.multiwriter:
type multiWriter struct {
writers []Writer
}
func (t *multiWriter) Write(p []byte) (n int, err error) {
...
}
...
func MultiWriter(writers ...Writer) Writer {
...
return &multiWriter{allWriters}
}
This would work even if instead of &multiWriter{allWriters}, the function returned multiWriter value, and func (t *multiWriter) Write had a value receiver.
Is there a reason why go standard library consistently prefers pointer receivers?
multiWriter's methods could indeed skip the pointer receivers, but since MultiWriter returns an interface and interfaces in Go only contain a type and a pointer to the data, you would need to separately allocate a struct anyway.
One interesting point here is that, as far as I can tell, this is an implementation detail and not part of the spec. One could imagine an alternative Go implementation which uses a different representation of interfaces in memory, potentially allowing small structs to fit directly in interface values without pointers.
Is there a reason why go standard library consistently prefers pointer receivers
No.
Sometimes it's for compatibility reasons (e.g. because the first version would not have worked on value receivers). Sometimes it's for consistency reasons. Sometimes it's author preference. There is not much to see or learn here.
Hey guys this code is part of a mock client, mock server interaction. I am having trouble understanding context.
Here I explicitly "associate" my tracker interface with context using 'WithValue' and then inject it into my request using WithContext. But when I check if my request's context contains the tracker interface I am returned the error "This context should contain a tracker" . What is it about context and WithValue that I am just not understanding?
var tracker Tracker
ctx := context.WithValue(context.Background(), contextKey, tracker)
req := httptest.NewRequest("GET", "localhost:12345/test", nil)
req.Header.Add(HEADER)
req = req.WithContext(ctx)
_, ok := ctx.Value(contextKey).(Tracker)
if !ok {
log.Fatal("1: This context should contain a tracker")
}
Tracker is an interface, and it's not set to anything, so it's nil. So, it can't change nil to a Tracker, so it fails.
https://play.golang.org/p/4-KQXlCR8vD
The problem isn't that tracker is nil, the problem is that it doesn't contain a value of a concrete type that implements Tracker. The value of tracker could be nil, and this would work, but it has to be a "typed" nil.
The type assertion fails, because type assertions and type switches only work when the instance being asserted has a concrete type. A value can be of a concrete type by declaration , assignment, type assertion , or a type switch case.
When you do the type assertion ctx.Value(contextKey).(Tracker)
There's (conceptually) a 2-step process to this:
Determine the ctx.Value(contextKey)'s concrete type.
Determine whether that concrete type implements Tracker.
Here's a playground example that hopefully illustrates this better: https://play.golang.org/p/ojYzLObkisd
The DoAny() function in there is emulating what is happening when you put your tracker into context and then try to retrieve it with the type assertion.
I know this is just a basic example, but it's not very good practice to use var something SomeInterfaceType, even if you do assign it a value. You should use concrete types for that. Or even better, just use type inference, and you won't have to worry about it. For example:
type Foo interface {
DoFoo() string
}
type MyFoo struct {}
func (f *MyFoo) DoFoo() string {
return "some foo value"
}
// not so good
var f Foo = new(MyFoo)
// good
var f *MyFoo = new(MyFoo)
// better
f := new(MyFoo)
This leverages the fact that interfaces are implicit in Go, and leads to much more obvious and maintainable code, especially in larger projects. Declaring a variable with an interface type is essentially making your variable poloymorphic, but the real power of interfaces isn't polymorphism. The real power is in using them as "functional requirements" for your package's exposed functions/methods. One rule that illustrates this really well is "Accept interfaces, return structs".
EDIT:
I've edited my original answer to correct some mistakes and make some improvements. I also would like to answer a follow-up question from the OP:
what I did not understand is that unless you have an object that utilizes that tracker's methods your interface is nil. Is this correct thinking?
I think what you're trying to say is correct, but the words used aren't quite right. First, there are no objects in Go, as it is not object-oriented. Where in OOP languages, objects hold instances of types, Go uses variables and constants to hold instances of types. So the concept exists, but not by the same name. So your tracker variable will be an instance of a type that satisfies your Tracker interface, but its value with be nil unless you assign it a non-nil instance of a type that satisfies the Tracker interface.
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.
I am trying to implement a set of functions in go. The context is an event server; I would like to prevent (or at least warn) adding the same handler more than once for an event.
I have read that maps are idiomatic to use as sets because of the ease of checking for membership:
if _, ok := set[item]; ok {
// don't add item
} else {
// do add item
}
I'm having some trouble with using this paradigm for functions though. Here is my first attempt:
// this is not the actual signature
type EventResponse func(args interface{})
type EventResponseSet map[*EventResponse]struct{}
func (ers EventResponseSet) Add(r EventResponse) {
if _, ok := ers[&r]; ok {
// warn here
return
}
ers[&r] = struct{}{}
}
func (ers EventResponseSet) Remove(r EventResponse) {
// if key is not there, doesn't matter
delete(ers, &r)
}
It is clear why this doesn't work: functions are not reference types in Go, though some people will tell you they are. I have proof, though we shouldn't need it since the language specification says that everything other than maps, slices, and pointers are passed by value.
Attempt 2:
func (ers EventResponseSet) Add(r *EventResponse) {
// ...
}
This has a couple of problems:
Any EventResponse has to be declared like fn := func(args interface{}){} because you can't address functions declared in the usual manner.
You can't pass a closure at all.
Using a wrapper is not an option because any function passed to the wrapper will get a new address from the wrapper - no function will be uniquely identifiable by address, and all this careful planning is for nought.
Is it silly of me to not accept defining functions as variables as a solution? Is there another (good) solution?
To be clear, I accept that there are cases that I can't catch (closures), and that's fine. The use case that I envision is defining a bunch of handlers and being relatively safe that I won't accidentally add one to the same event twice, if that makes sense.
You could use reflect.Value presented by Uvelichitel, or the function address as a string acquired by fmt.Sprint() or the address as uintptr acquired by reflect.Value.Pointer() (more in the answer How to compare 2 functions in Go?), but I recommend against it.
Since the language spec does not allow to compare function values, nor does it allow to take their addresses, you have no guarantee that something that works at a time in your program will work always, including a specific run, and including different (future) Go compilers. I would not use it.
Since the spec is strict about this, this means compilers are allowed to generate code that would for example change the address of a function at runtime (e.g. unload an unused function, then load it again later if needed again). I don't know about such behavior currently, but this doesn't mean that a future Go compiler will not take advantage of such thing.
If you store a function address (in whatever format), that value does not count as keeping the function value anymore. And if no one else would "own" the function value anymore, the generated code (and the Go runtime) would be "free" to modify / relocate the function (and thus changing its address) – without violating the spec and Go's type safety. So you could not be rightfully angry at and blame the compiler, but only yourself.
If you want to check against reusing, you could work with interface values.
Let's say you need functions with signature:
func(p ParamType) RetType
Create an interface:
type EventResponse interface {
Do(p ParamType) RetType
}
For example, you could have an unexported struct type, and a pointer to it could implement your EventResponse interface. Make an exported function to return the single value, so no new values may be created.
E.g.:
type myEvtResp struct{}
func (m *myEvtResp) Do(p ParamType) RetType {
// Your logic comes here
}
var single = &myEvtResp{}
func Get() EventResponse { return single }
Is it really needed to hide the implementation in a package, and only create and "publish" a single instance? Unfortunately yes, because else you could create other value like &myEvtResp{} which may be different pointers still having the same Do() method, but the interface wrapper values might not be equal:
Interface values are comparable. Two interface values are equal if they have identical dynamic types and equal dynamic values or if both have value nil.
[...and...]
Pointer values are comparable. Two pointer values are equal if they point to the same variable or if both have value nil. Pointers to distinct zero-size variables may or may not be equal.
The type *myEvtResp implements EventResponse and so you can register a value of it (the only value, accessible via Get()). You can have a map of type map[EventResponse]bool in which you may store your registered handlers, the interface values as keys, and true as values. Indexing a map with a key that is not in the map yields the zero value of the value type of the map. So if the value type of the map is bool, indexing it with a non-existing key will result in false – telling it's not in the map. Indexing with an already registered EventResponse (an existing key) will result in the stored value – true – telling it's in the map, it's already registered.
You can simply check if one already been registered:
type EventResponseSet map[*EventResponse]bool
func (ers EventResponseSet) Add(r EventResponse) {
if ers[r] {
// warn here
return
}
ers[r] = true
}
Closing: This may seem a little too much hassle just to avoid duplicated use. I agree, and I wouldn't go for it. But if you want to...
Which functions you mean to be equal? Comparability is not defined for functions types in language specification. reflect.Value gives you the desired behaviour more or less
type EventResponseSet map[reflect.Value]struct{}
set := make(EventResponseSet)
if _, ok := set[reflect.ValueOf(item)]; ok {
// don't add item
} else {
// do add item
set[reflect.ValueOf(item)] = struct{}{}
}
this assertion will treat as equal items produced by assignments only
//for example
item1 := fmt.Println
item2 := fmt.Println
item3 := item1
//would have all same reflect.Value
but I don't think this behaviour guaranteed by any documentation.
I have an object like os.Stdout and I want to know if it supports io.WriteCloser on my platform. I can get the type of my object, but it doesn't tell me anything about interfaces.
package main
import ("fmt"; "reflect"; "os")
func main() {
fmt.Println(reflect.TypeOf(os.Stdout))
}
This code prints *os.File to console.
I can manually lookup if os.File matches io.WriteCloser methods, but I am curious to get all interfaces that this object supports.
It's not an exactly answer on the question, because it is not for runtime. Anyway I think it maybe useful
Take a look on https://golang.org/lib/godoc/analysis/help.html
godoc has static analysis features. And it can display your type implements relations.
For example you can run godoc -http=:8081 -analysis=type and get all your packages documentation with type analysis.
To expand on the comment from #Volker regarding type assertions, that would look like this:
_, implements := interface{}(os.Stdout).(io.Reader)
It casts os.Stdout to an interface{} type and then attempts to assert that it is an io.Reader. Type assertions return two values; the first is the asserted value (or nil if assertion fails) and the second is a boolean indicating if the assertion was successful or not. If you omit capturing the second return value then a failed assertion will cause a panic.
For alternative, possibly more generic or runtime requirements the types package may have some useful functions based on reflection: https://godoc.org/golang.org/x/tools/go/types