Getting warning while running command "go get" [duplicate] - pointers

I have this problem which seems a bit weird to me. Take a look at this snippet of code:
package coreinterfaces
type FilterInterface interface {
Filter(s *string) bool
}
type FieldFilter struct {
Key string
Val string
}
func (ff *FieldFilter) Filter(s *string) bool {
// Some code
}
type FilterMapInterface interface {
AddFilter(f *FilterInterface) uuid.UUID
RemoveFilter(i uuid.UUID)
GetFilterByID(i uuid.UUID) *FilterInterface
}
type FilterMap struct {
mutex sync.Mutex
Filters map[uuid.UUID]FilterInterface
}
func (fp *FilterMap) AddFilter(f *FilterInterface) uuid.UUID {
// Some code
}
func (fp *FilterMap) RemoveFilter(i uuid.UUID) {
// Some code
}
func (fp *FilterMap) GetFilterByID(i uuid.UUID) *FilterInterface {
// Some code
}
On some other package, I have the following code:
func DoFilter() {
fieldfilter := &coreinterfaces.FieldFilter{Key: "app", Val: "152511"}
filtermap := &coreinterfaces.FilterMap{}
_ = filtermap.AddFilter(fieldfilter) // <--- Exception is raised here
}
The run-time won't accept the line mentioned because
"cannot use fieldfilter (type *coreinterfaces.FieldFilter) as type
*coreinterfaces.FilterInterface in argument to fieldint.AddFilter:
*coreinterfaces.FilterInterface is pointer to interface, not interface"
However, when changing the code to:
func DoBid() error {
bs := string(b)
var ifilterfield coreinterfaces.FilterInterface
fieldfilter := &coreinterfaces.FieldFilter{Key: "app", Val: "152511"}
ifilterfield = fieldfilter
filtermap := &coreinterfaces.FilterMap{}
_ = filtermap.AddFilter(&ifilterfield)
}
Everything is alright and when debugging the application it really seems to include
I'm a bit confused on this topic. When looking at other blog posts and stack overflow threads discussing this exact same issue (for example - This, or
This) the first snippet which raises this exception should work, because both fieldfilter and fieldmap are initialized as pointers to interfaces, rather than value of interfaces. I haven't been able to wrap my head around what actually happens here that I need to change in order for me not to declare a FieldInterface and assign the implementation for that interface. There must be an elegant way to do this.

So you're confusing two concepts here. A pointer to a struct and a pointer to an interface are not the same. An interface can store either a struct directly or a pointer to a struct. In the latter case, you still just use the interface directly, not a pointer to the interface. For example:
type Fooer interface {
Dummy()
}
type Foo struct{}
func (f Foo) Dummy() {}
func main() {
var f1 Foo
var f2 *Foo = &Foo{}
DoFoo(f1)
DoFoo(f2)
}
func DoFoo(f Fooer) {
fmt.Printf("[%T] %+v\n", f, f)
}
Output:
[main.Foo] {}
[*main.Foo] &{}
https://play.golang.org/p/I7H_pv5H3Xl
In both cases, the f variable in DoFoo is just an interface, not a pointer to an interface. However, when storing f2, the interface holds a pointer to a Foo structure.
Pointers to interfaces are almost never useful. In fact, the Go runtime was specifically changed a few versions back to no longer automatically dereference interface pointers (like it does for structure pointers), to discourage their use. In the overwhelming majority of cases, a pointer to an interface reflects a misunderstanding of how interfaces are supposed to work.
However, there is a limitation on interfaces. If you pass a structure directly into an interface, only value methods of that type (ie. func (f Foo) Dummy(), not func (f *Foo) Dummy()) can be used to fulfill the interface. This is because you're storing a copy of the original structure in the interface, so pointer methods would have unexpected effects (ie. unable to alter the original structure). Thus the default rule of thumb is to store pointers to structures in interfaces, unless there's a compelling reason not to.
Specifically with your code, if you change the AddFilter function signature to:
func (fp *FilterMap) AddFilter(f FilterInterface) uuid.UUID
And the GetFilterByID signature to:
func (fp *FilterMap) GetFilterByID(i uuid.UUID) FilterInterface
Your code will work as expected. fieldfilter is of type *FieldFilter, which fullfills the FilterInterface interface type, and thus AddFilter will accept it.
Here's a couple of good references for understanding how methods, types, and interfaces work and integrate with each other in Go:
https://medium.com/#agileseeker/go-interfaces-pointers-4d1d98d5c9c6
https://www.goinggo.net/2014/05/methods-interfaces-and-embedded-types.html
https://blog.golang.org/laws-of-reflection

GetFilterByID(i uuid.UUID) *FilterInterface
When I get this error, it's usually because I'm specifying a pointer to an interface instead of an interface ( that will actually be a pointer to my struct that fulfills the interface ).
There's a valid use for *interface{...} but more commonly I just am thinking 'this is a pointer' instead of 'this is an interface which happens to be a pointer in the code I'm writing'

Related

golang function return interface pointer

Can some one help me understand why it's failing to use the syntax like [Error 1] and [Error 2]?, why [ok 1] is possible and working just fine.
Is the basic design to use Animal as field to serve as generic type good? or any thing bad about it? or any better solution suggested?
package main
import (
pp "github.com/davecgh/go-spew/spew"
)
type Cat struct {
Name string
Age int
}
type Animal interface{}
type House struct {
Name string
Pet *Animal
}
func config() *Animal {
c := Cat{"miao miao", 12}
// return &Animal(c) //fail to take address directly [Error 1]
// return &(Animal(c)) //fail to take address directly [Error 2]
a := Animal(c) //[Ok 1]
return &a
}
func main() {
pp.Dump(config())
pp.Dump(*config())
pp.Dump((*config()).(Cat)) //<-------- we want this
pp.Dump((*config()).(Cat).Name)
pp.Dump("---------------")
cfg := config()
pp.Dump(&cfg)
pp.Dump(*cfg)
pp.Dump((*cfg).(Cat)) //<-------- we want this
pp.Dump((*cfg).(Cat).Name)
pp.Dump("---------------")
}
Ok, two thing:
You cannot take the address of the result of a conversion directly, as it is not "addressable". See the section of the spec about the address-of operator for more information.
Why are you using a pointer to an interface at all? In all my projects I have only ever used an interface pointer once. An interface pointer is basically a pointer to a pointer, sometimes needed, but very rare. Internally interfaces are a type/pointer pair. So unless you need to modify the interface value instead of the value the interface holds then you do not need a pointer. This post may be of interest to you.

How to implement interfaces in following code?

I have the following code and I want to use interfaces:
Current code:
import (
"github.com/dorzheh/deployer/ui/dialog_ui"
. "github.com/dorzheh/go-dialog"
)
// all methods in https://github.com/dorzheh/deployer/blob/master/ui/dialog_ui/dialog_ui.go#L28
type Pb struct {
sleep time.Duration
step int
}
type DialogUi struct {
*Dialog //The source is https://github.com/dorzheh/go-dialog/blob/master/dialog.go#L34
Pb *Pb
}
I am trying to implement interfaces this way:
import (
"testing"
// . "github.com/dorzheh/go-dialog"
//"github.com/dorzheh/deployer/ui/dialog_ui"
)
type PBifaceT interface {
Step() int
}
type TestDialogUiT struct {
Pb *PBifaceT
}
func TestUiValidateUser(t *testing.T) {
x := dialog_ui.TestDialogUiT{}
PbPb := ImplPBifaceT{}
x.Pb = PbPb
parentId := x.Pb.Step()
t.Logf(fmt.Sprintf("%v", parentId))
}
I've made a playground. As you can see it runs in the following error:
prog.go:23: cannot use PbPb (type ImplPBifaceT) as type *PBifaceT in assignment:
*PBifaceT is pointer to interface, not interface
prog.go:25: x.Pb.Step undefined (type *PBifaceT is pointer to interface, not interface)
I tried to convert them in this playground:
func NewD() *PBifaceT {
// var err error
var res =new(ImplPBifaceT)
return (*PBifaceT)(res)
}
func main() {
x := TestDialogUiT{}
x.Pb = NewD()
parentId := x.Pb.Step()
fmt.Sprintf("%v", parentId)
}
The issue:
prog.go:23: cannot convert res (type *ImplPBifaceT) to type *PBifaceT
prog.go:30: x.Pb.Step undefined (type *PBifaceT is pointer to interface, not interface)
Are you sure you need your PbĀ field as a *PBifaceT.
If you keep it as a
type TestDialogUiT struct {
Pb *PBifaceT
}
and you do
x := TestDialogUiT{}
PbPb := ImplPBifaceT{}
x.Pb = PBifaceT(PbPb)
parentId := x.Pb.Step()
fmt.Printf("%v", parentId)
It works properly..
Take a look at this playground and see if it can help.
I'd suggest you to take a look at this tutorial and this doc.
I'd suggest you also to read this SO answer which explains a bit of how you shouldn't want to use interface pointers.
Background: In Go you pass around a pointer to something because of two reasons:
1) You want because your struct is really large and you want to avoid copying
2) you need to because the calee wants to modify the original (this is typical for methods with a pointer receiver). Now an interface value is really tiny (just two words) so reason 1 to pass a pointer to an interface value does not apply.
Reason 2 does not apply in most cases as passing a pointer to an interface value will allow you to change the interface value itself, but most often you would like to modify the value stored inside the interface value. This value stored inside the interface value often is a pointer value which allows to change the value of a struct by calling methods on an interface value which wrapps a pointer to this struct. This sounds complicated but isn't: The novice Go programmer just doesn't use pointers to interfaces (as this won't do any good) and the experienced Go programmer doesn't use pointers to interfaces (as it won't do much good) unless he needs to modify an interface value, typically during reflection.
You can use Pb by link, you were just missing pointer reference while assigning.
package main
import (
"fmt"
)
type PBifaceT interface {
Step() int
}
type TestDialogUiT struct {
Pb PBifaceT
}
type ImplPBifaceT struct {
}
func (m *ImplPBifaceT) Step() int {
return 0
}
func main() {
x := TestDialogUiT{}
PbPb := &ImplPBifaceT{}
x.Pb = PbPb
parentId := x.Pb.Step()
fmt.Printf("%v", parentId)
}
Please refer this playground link: https://play.golang.org/p/N7quQFpYU0
Changes were at line 12, 17, 23 & 27.
Do not use pointer to interface unless you are sure that's what you want, see Pb *PBifaceT inside TestDialogUiT. If you change it to just Pb PBifaceT your playground link just works.
An interface is already a pointer.

golang get the reflect.Type of a type

Is it possible and how to get the reflect.Type of a type without creating an object from the type and calling on it reflect.TypeOf(obj)
What in java will be: MyType.class
You can achieve this without an instantiation with the following syntax;
package main
import (
"fmt"
"reflect"
)
type Test struct {
}
func main() {
fmt.Println(reflect.TypeOf((*Test)(nil)).Elem())
}
play; https://play.golang.org/p/SkmBNt5Js6
Also, it's demonstrated in the reflect example here; https://golang.org/pkg/reflect/#example_TypeOf
No you can't have it directly, because in Go structs have no accessible fields to get their type.
One may think of tweaking it by doing the following:
type object struct {}
func main() {
var obj object
t := reflect.TypeOf(object)
fmt.Println(t)
// main.object
}
However, in Go every variable is initialized with its zero value, so this is perfectly equivalent to:
t := reflect.TypeOf(object{})
// main.object
If you look at Golang's source code, you'll see that reflect.Type is an interface implemented differently according to types, however you do not have access to those informations.
But, what you can do is get the type of a pointer to the struct and from there, get the actual type. The process is the same, except that a pointer's zero value is nil, so it takes less time to instantiate:
func main() {
ptr_t := reflect.TypeOf((*object)(nil))
fmt.Println(ptr_t)
// *main.object
t := ptr_t.Elem()
fmt.Println(t)
// main.object
}

Why can't the interface be implemented with pointer receivers

I'm confused as to why this fails to compile with:
impossible type assertion:
Faz does not implement Foo (Bar method has pointer receiver)
if I make the receiver for Faz.Bar a Faz value rather than a Faz pointer then it compiles fine, but I thought it was always better to have pointer receivers so values aren't being copied around?
package main
import (
"log"
)
func main() {
foo := New().(Faz)
log.Println(foo)
}
type Foo interface {
Bar() string
}
func New() Foo {
return &Faz{}
}
type Faz struct {
}
func (f *Faz) Bar() string {
return `Bar`
}
Because it's *Faz not Faz.
func main() {
foo := New().(*Faz)
log.Println(foo)
}
I think the answer to this question needs to a more retrospective approach towards the grammar, and how would implement it through software engineering. (Excuse the over simplification)
First a quick flashback of what are types?
They are just memory blocks with compiler logic on top. What makes an array different from a string is what the compiler allows us to do with those memory blocks. (Think deeper and you may begin to realize the true difference between strongly typed and dynamically typed languages.)
Now next you need to realize that pointers are their own types per say. *variable is a different memory block (aka type) than variable. It's just that the compiler always assumes that content of *variable is always going to be an address to a memory block of type to the right of the declaration along with other restriction/features it imposes.
Then let's recap what an interface is.
Pseudo-scientific definition: A set of requirements for any first class citizen to be of a specific type.
Translated to software engineering- any block of memory (types) that has the same memory structure (think back to structure packing) associated to it as described in a contract (interface) can be passed around as with the type name that the contract mentions.
Now you may begin to realize that when you say
func (f *Faz) Bar() string is f's block of memory holding a function, where f's type is a pointer to Faz
where areas
func (f Faz) Bar() string is f's block of memory, where f's type is Faz
So when you are saying that a variable of *Faz type is satisfying a contract, then how can you assume that a variable of Faz type will qualify as interface type in the code? Chose who satisfies your contract, and only that type can assume the interface type in your code.

How to force passing parameter as a pointer in Go?

I am implementing an application layer network protocol which uses JSON in Go.
func ReadMessage(conn net.Conn, returnMessage interface{}) bool {
messageBytes := // read from conn
error := json.Unmarshal(messageBytes, &returnMessage)
if error != nil {
return false
}
return true
}
The function takes a struct as its second parameter where the message is unmarshalled. The function can be called like this:
msg := MessageType1{}
ok := ReadMessage(conn, &msg)
Or without the ampersand (&)
msg := MessageType1{}
ok := ReadMessage(conn, msg)
which will compile, but not do what is should as the struct is passed as a copy, not as a reference and the original msg will remain empty. So I'd like to force passing the struct by reference and catch this error at compile time.
Changing the parameter type to *interface{} will not compile:
cannot use &msg (type *MessageType1) as type *interface {} in function argument:
*interface {} is pointer to interface, not interface
Is there some Go style way of doing this correctly?
There is not a way to do this in the function declaration.
You can use reflection though and panic at runtime when the argument is not a pointer.
However maybe you should consider changing the design of your code. The concrete type of the argument should not matter. It either implements the interface you need or not.
Demo: http://play.golang.org/p/7Dw0EkFzbx
Since Go 1.18 you can do this using generics:
func test[T any](dst *T) {
//Do something with dst
}
You can't enforce this as *T always has the method set of T. Thus both implement the interface.
From the spec:
The method set of any other type T consists of all methods with receiver type T. The method set of the corresponding pointer type *T is the set of all methods with receiver *T or T (that is, it also contains the method set of T).
What you can do instead is to use the language's ability to return multiple values in your function, as Volker already stated:
func ReadMessage(conn net.Conn) (interface{}, bool) {
var returnMessage interface{}
messageBytes := // read from conn
error := json.Unmarshal(messageBytes, &returnMessage)
if error != nil {
return nil, false
}
return returnMessage, true
}
You should also consider not returning type interface{} but some meaningful type.

Resources