I have defined two functions. When I pass a pointer to it, I can't get the defined method. Why is this?
type Visitor interface {
work()
}
func test(v *Visitor) {
v.work() // error
}
func test1(v Visitor) {
v.work() // ok
}
Error:
v.work undefined (type *Visitor is pointer to interface, not
interface)
anyone know why, ths
func test(v *Visitor) {
v.work() // error
}
v.work() ought to be a method call. But v is of type *Visitor, a pointer to interface. A pointer to interface has 0 methods, it does not implement anything (except the empty interface interface{}).
When using a non-pointer, the value v (or rather its type) has a method work(), so you can call that:
func test(v Visitor) {
v.work() // ok
}
Here v.work() works, because the v is of type Visitor which is an interface, and it contains the method work().
What may be confusing is that if you add method to a (non-pointer, non-interface) concrete type, the respective pointer type will also have that method, and you can call that. This is in Spec: Method sets:
A type may have a method set associated with it. The method set of an interface type is its interface. The method set of any other type T consists of all methods declared with receiver type T. The method set of the corresponding pointer type *T is the set of all methods declared with receiver *T or T (that is, it also contains the method set of T). Further rules apply to structs containing embedded fields, as described in the section on struct types. Any other type has an empty method set. In a method set, each method must have a unique non-blank method name.
The difference is that you tried the same with interface type, which won't work. It works with concrete (non-interface) types. Lesson is to never use pointer to interface unless you can reason why it is needed (it is rarely needed).
As the error clearly states:
v.work undefined (type *Visitor is pointer to interface, not
interface)
This is because the work() function is called on pointer to the receiver but defined on value.
type Visitor interface {
work()
}
But you are passing pointer type receiver in second case in which you are getting an error.
In Golang spec Method sets are defined as:
A type may have a method set associated with it. The method set of an
interface type is its interface. The method set of any other type T
consists of all methods declared with receiver type T. The method set
of the corresponding pointer type *T is the set of all methods
declared with receiver *T or T (that is, it also contains the method
set of T). Further rules apply to structs containing embedded fields,
as described in the section on struct types. Any other type has an
empty method set. In a method set, each method must have a unique
non-blank method name.
One approach you can do is Implement the interface by using the struct on which you can call the method work().
package main
import "fmt"
type Visitor struct{}
type Visit interface {
work()
}
func test(v Visit) {
v.work() // error
fmt.Printf("%+v", v)
}
func (v *Visitor) work(){}
func main(){
v := Visitor{}
test(&v)
}
Working Code on Go playground
Related
In the following example, I'd like to call the setvalue() of the b object via an interface procedure.
I'd like to use an interface because I need to insert different kinds of objects in a list, possibly very big, each obeying a common interface.
However the compiler complains with the following error :
./tests.go:27:6: cannot use newbox(3) (type box) as type container in assignment:
box does not implement container (setValue method has pointer receiver)
Probably I have to define the interface differently, but how?
I know I could transform the setvalue procedure in a function, returning the updated box, but since the object can be very large, and he procedure will be called several times, i'd like to pass the object via a pointer.
Really isn't there a way to define an interface method that receive the calling structure via a pointer?
package main
import "fmt"
type container interface {
setValue (val int)
}
//--------------------------------------
// box is a kind of container
type box struct {
value int
}
func newbox (x int) box {
return box {x}
}
func (cnt *box) setValue(val int) {
(*cnt).value = val
}
// -----------------------------------------------
func main() {
var b container = newbox(3) // HERE IS THE ERROR
fmt.Printf("%v\n",b)
b.setValue(5)
fmt.Printf("%v\n",b)
}
In kubectl/run.go in Kubernetes code, the Generate function has a result list of these two types:
runtime.Object, error
The last line of the function is:
return &deployment, nil
runtime is imported:
k8s.io/apimachinery/pkg/runtime
I got runtime by running go get on that import statement, and Object is defined in interfaces.go:
type Object interface {
GetObjectKind() schema.ObjectKind
DeepCopyObject() Object
}
(And I found the same code on the web here.)
The address operator creates a pointer... more specifically, the Go spec states:
For an operand x of type T, the address operation &x generates a pointer of type *T to x.
and pointers have a type distinct from their base type:
A pointer type denotes the set of all pointers to variables of a given type, called the base type of the pointer.
How does &deployment satisfy the runtime.Object type?
My best guess so far is that deployment implements the runtime.Object interface, and mapping &deployment to runtime.Object satisfies this rule of assignability:
T is an interface type and x implements T.
and that a return statement mapping to a result list type is equivalent to assignment in this respect. Is this correct? If not, is there another part of the specification or documentation that explains it?
deployment is a local variable, its declaration:
deployment := extensionsv1beta1.Deployment{
// ...
}
Where extensionsv1beta1 from the imports:
import (
// ...
extensionsv1beta1 "k8s.io/api/extensions/v1beta1"
// ...
)
Doc of extensionsv1beta1.Deployment. Its definition is:
type Deployment struct {
metav1.TypeMeta `json:",inline"`
// ...other fields...
}
It embeds metav1.TypeMeta, which has a method GetObjectKind() method with pointer receiver. This means a pointer to Deployment also has this method, because Spec: Struct types:
Given a struct type S and a defined type T, promoted methods are included in the method set of the struct as follows:
If S contains an embedded field T, the method sets of S and *S both include promoted methods with receiver T. The method set of *S also includes promoted methods with receiver *T.
And Deployment has a "direct" DeepCopyObject() method, again with pointer receiver. So the method set of *Deployment contains this method.
And last quoting Spec: Interface types:
An interface type specifies a method set called its interface. A variable of interface type can store a value of any type with a method set that is any superset of the interface. Such a type is said to implement the interface.
So this means the method set of *Deployment has all the methods defined by Object, or in other words: the method set of *Deployment is a superset of the method set of Object, so *Deployment implements Object.
deployment is of type extensionsv1beta1.Deployment, which means &deployment is of type *extensionsv1beta1.Deployment, which we showed above that it implements Object; so the value &deployment can be assigned to or be stored in a variable of type Object.
I am learning Go and I am reading Go's official documentation about net/http, and I write following code from doc for test:
package main
import (
"net/http"
"fmt"
)
func main() {
client := &http.Client{}
resp, _ := client.Get("http://example.com")
fmt.Println(resp)
}
http.Client is a struct, but I do not know why there is a & pointer prefixed. I think creating a http.Client reference is not necessary. And why does the client variable have a Get method? I am reading the source code of net/http, it defines the Client struct below:
type Client struct {
Transport RoundTripper
CheckRedirect func(req *Request, via []*Request) error
Jar CookieJar
Timeout time.Duration
}
The Client struct does not have a Get method defined; why does the client variable have a Get method?
I would really take the Go Tour to get a feeling of the language and its basic syntax first.
The type declaration you quoted only contains the fields of the struct, but not its methods. Methods are defined elsewhere, like functions but with a receiver added which designates the type they belong to. For example the definition of Client.Get() method is this:
func (c *Client) Get(url string) (resp *Response, err error) {
req, err := NewRequest("GET", url, nil)
if err != nil {
return nil, err
}
return c.Do(req)
}
The part before the method name is called the receiver, and that designates the type the method belogns to (*Client in this example). See Spec: Method declarations for more details.
The & is an address operator, it takes the address of its operand. In this case the local variable client will be of type *http.Client. http.Client{} is a composite literal which creates a value of the struct type http.Client, and & takes the address of the anonymous variable where this struct value is stored:
Taking the address of a composite literal generates a pointer to a unique variable initialized with the literal's value.
It is used so that the client variable will be a pointer to an http.Client value, one that is encouraged to be shared and reused:
The Client's Transport typically has internal state (cached TCP connections), so Clients should be reused instead of created as needed. Clients are safe for concurrent use by multiple goroutines.
And if client is a pointer, you are free to pass it around to other functions, only the pointer value will be copied, not the pointed http.Client struct, so the struct itself (the http.Client value) will be reused. Should you not use a pointer, if you would pass it to other functions, the struct itself would be copied and not reused.
Note that in this simple example it doesn't really matter, as even though all methods of http.Client are declared with pointer receiver, you can still call pointer methods on non-pointer variables, as client.Get() would be a shorthand for (&client).Get(). This is mentioned in Spec: Calls:
If x is addressable and &x's method set contains m, x.m() is shorthand for (&x).m().
So even though the & address operator is not needed in this simple example, it's good to keep the habit of using it, should the example grow or should you write code where this does matter (e.g. you pass around the created client).
The situation I have now is the same as was asked about in this thread: Meaning of a struct with embedded anonymous interface?
type A interface {
Foo() string
}
type B struct {
A
bar string
}
Idiomatically, coming from a backround in OOP languages, what it looks like this pattern is "trying to say" to me is that B must implement interface A. But I get by now that "Go is different". So, rather than the compile-time check I expected at first, this is happy to compile with or without a
func (B) Foo() string { .... }
present. As the above question points out (paraphrased): "using embedded interfaces in structs is great for when you only want to implement /part/ of an interface".
Presumably, this is because what is happening with this embed is just like in every other case - a value of type B would have an anonymous interface value of type A, as a field. Personally while I find that orthogonality comforting, I also find it confusing that the reflection package would then let me get methods of A directly from B's type this way, and not error/nil if no method with receiver B is present. But - this question isn't about the thinking behind that - it is about how that interface value is initialized after b := B{}:
func main() {
bType := reflect.TypeOf(B{})
bMeth, has := bType.MethodByName("Foo")
if has {
fmt.Printf("HAS IT: %s\n",bMeth.Type.Kind())
res := bMeth.Func.Call([]reflect.Value{reflect.ValueOf(B{})})
val := res[0].Interface()
fmt.Println(val)
} else {
fmt.Println("DOESNT HAS IT")
}
}
When this is run, it causes a horrible panic
HAS IT: func
panic: runtime error: invalid memory address or nil pointer dereference
... or doesn't - depending on if the compiler/runtime was able to find the above method. So: How can I detect that situation before I trigger it?
That is - is there something about the bMeth value I can use to see that there is no "real" implementation present in the reflection-returned returned Method and func values? Is that more precisely something like "is the pointer to the function in the function table of the anonymous interface value in zero", or what exactly is going on with methods you pull from an interface with reflection where there is no implementation?
Wrapping the whole thing in a goroutine and attempting to run the function under defer/panic isn't the answer - not only because of the expense of the panic/defer but because the function in general might, if it does exist, have side effects I don't want right now...
Do I want something like a run-time implementation that mirrors the compiler's type check? Or is there an easier way? Am I thinking about this incorrectly?
Above example in a Go playground
You needn't reflection to my mind
method_in_table := B.Foo
fmt.Printf("%T \n", method_in_table)
will output you
func(main.B) string
Interface type A initialized at predeclared nil which has no dynamic type
var a A
if a==nil{
fmt.Printf("It's nil")
}
a.Foo()
will give you same error. So practical check can be just
if b.A != nil { b.Foo()}
This question is old with some good answers, but none presents the possibility that this can be done.
Before presenting the solution: I think it's not your job to make sure the implementation does not panic because it fails to set an embedded interface field. Someone could pass an implementation which explicitly defines the methods in which
panic() is called explicitly. You could not detect that case, yet, that implementation wouldn't be any better than a nil embedded interface field.
OK, so how to tell if a method cannot be called because it would panic due to the implementation not being available because the embedded interface field is nil?
You said you can't / don't want to call the method and recover from a panic because if the method is available, this would call it and have its side effect.
The fact is that we don't have to call it. We can just refer to the method via an instance (not type), and then the actual receiver has to be resolved. Of course if the receiver would be the dynamic value of an embedded interface, and if that interface is nil, the resolving will cause a runtime panic, but the method will not be called even if the embedded interface is not nil. Note that this is in fact a Method value, and obtaining a method value evaluates and saves the receiver. This receiver evaluation is what will fail.
Let's see an example:
type A interface {
Foo() string
}
type B struct {
A
}
func (b B) Int() int {
fmt.Println("B.Int() called")
return 0
}
func main() {
b := B{}
_ = b.Int
fmt.Println("We got this far, b.Int is realized")
}
What will this program output? Only "We got this far, b.Int is realized". Because the Int() method is explicitly defined for the B type, and so b.Int can be resolved. And since it's not called, "B.Int() called" will not be printed.
What if we do this:
_ = b.Foo
Since Foo is a promoted method from B.A embedded interface, and b.A is nil, resolving b.Foo will fail at runtime, and produce a runtime error, something like this:
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x47d382]
goroutine 1 [running]:
main.main()
/tmp/sandbox877757882/prog.go:24 +0x2
But we can recover from this:
defer func() {
if r := recover(); r != nil {
fmt.Println("Recovered:", r)
fmt.Println("This means b.Foo is not realized!")
}
}()
_ = b.Foo
This will output:
Recovered: runtime error: invalid memory address or nil pointer dereference
This means b.Foo is not realized!
Try the examples on the Go Playground.
Let me put my two cents in, after you've already received good answers for your question.
Presumably, this is because what is happening with this embed is just like in every other case - a value of type B would have an anonymous interface value of type A, as a field.
You've basically solved the problem here. This is just a field, but because it's anonymous all its methods are being promoted and you can use them directly on the struct. This is not only related to interfaces, but the problem you've pointed to exists within ordinary structures as well:
package main
type A struct {
}
func (a A) Foo() {
}
type B struct {
*A
}
func main() {
B{}.Foo()
}
This will cause panic. I believe this is expected: we're saying B embeds *A, but then leave it uninitialised, so what am I thinking? We could try to find an analogy here with, for example, C++ and find out it is similar to a null pointer in C++ – how do we deal with it there? We either expect it to be non-null (by a contract) or need to check before using. The latter it what Uvelichitel suggested in the accepted answer and it's by no means correct and there is no better solution I think. Although it's not very plausible. We do expect the caller to know the method they're calling is a promoted method of an anonymous field which is a pointer (or interface) type and as such can be nil. As an author of such code I would either need to make sure it's never nil (contract) or state it clearly in documentation that a caller needs to check it (but why would I embed this type then instead of having normal field, I'm not sure).
It bothers me with interfaces though, because looking back at your example and making A an interface, we have a following problem:
package main
import "fmt"
type A interface {
Foo()
}
type B struct {
A
}
func main() {
var b interface{}
b = &B{}
// Nicely check whether interface is implemented
if a, ok := b.(A); ok {
a.Foo()
}
}
Whoops, panic. I explicitly don't use reflect package here to indicate your problem exists within "normal" language usage. I have an interface object b and want to check whether it implements interface A. The answer is yes, but I'm getting panic. Who is to blame? I would feel much more comforting saying the creator of object behind the interface b who advertise some functionality, but don't care to provide the implementation. As such I would like it to call a bad practice or at least force it to be clearly stated in the documentation rather than assuming ok in the above type assertion means actually ok.
It's getting too long and off topic I think. My answer to your question is then a mixture of already given answers: directly check A is not null and if it's not possible (you don't know the exact field promoting the method), hope for the best and blame someone else.
I don't think this is possible. From what I can see in reflect's documentation and code, there is no way to know, whether a method is defined on the type or promoted. Seems like panic-recover is the best you can do here.
There are 3 questions here.
An embedded interface does not mean "implements A". It's exactly the same as embedding any other type of object. If you want to implement A, just make a method: func (b B) Foo() string.
When you say:
using embedded interfaces in structs is great for when you only want to
implement /part/ of an interface
That does work, but you have to make sure to create the object properly. Think of it like wrapping an existing object:
type MyReadCloser struct {
io.ReadCloser
}
func (mrc *MyReadCloser) Read(p []byte) (int64, error) {
// do your custom read logic here
}
// you get `Close` for free
func main() {
// assuming we have some reader
var rc io.ReadCloser
// you have to build the object like this:
myReader := MyReadCloser{rc}
}
I'm not sure how Go does it internally, but conceptually it's as if it creates a Close method for you:
func (mrc *MyReadCloser) Close() error {
return mrc.ReadCloser.Close()
}
The panic is because A is nil. If you had:
type concrete string
func (c concrete) Foo() string {
return string(c)
}
func main() {
b := B{A: c("test")}
// etc...
}
It would work. In other words when you call:
bMeth.Func.Call([]reflect.Value{reflect.ValueOf(B{})})
That's:
B{}.Foo()
Which is:
B{}.A.Foo()
And A is nil so you get a panic.
As to the question about how to get only the methods directly implemented by an object (not methods implemented by an embedded field), I wasn't able to see a way using the reflect library. MethodByName gives no indication:
<func(main.B) string Value>
Internally that's basically a function like this:
func(b B) string {
return b.A.Foo()
}
And I don't think there's anything in reflect that allows you to peer into the internals of a function. I tried looping over the fields, grabbing their methods and comparing the two, but that doesn't work either.
I want to reflect to determine whether or not a Go interface contains certain method signatures. I've dynamically got the names and signatures, previously through reflection on a struct. Here's a simplified example:
package main
import "reflect"
func main() {
type Mover interface {
TurnLeft() bool
// TurnRight is missing.
}
// How would I check whether TurnRight() bool is specified in Mover?
reflect.TypeOf(Mover).MethodByName("TurnRight") // would suffice, but
// fails because you can't instantiate an interface
}
http://play.golang.org/p/Uaidml8KMV. Thanks for your help!
You can create a reflect.Type for a type with this trick:
tp := reflect.TypeOf((*Mover)(nil)).Elem()
That is, create a typed nil pointer and then get the type of what it points at.
A simple way to determine if a reflect.Type implements a particular method signature is to use its Implements method with an appropriate interface type. Something like this should do:
type TurnRighter interface {
TurnRight() bool
}
TurnRighterType := reflect.TypeOf((*TurnRighter)(nil)).Elem()
fmt.Println(tp.Implements(TurnRighterType))