golang make struct T implement I but not *T - go

I have a struct T that implements an interface I, but I want *T to not implement the interface. Is this possible?
That is, this should compile fine:
var obj I = T{}
but this should generate a compile error:
var obj I = &T{}
The reason is that it is a common mistake in my codebase to accidentally use *T as a certain interface I when it is expected that only T will be used.

Not possible. From the spec (emphasis mine):
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).

Related

Pass pointer as an interface type to the function

I am a new to Go and the behavior below confuses me:
package main
type Contractor struct{}
func (Contractor) doSomething() {}
type Puller interface {
doSomething()
}
func process(p Puller) {
//some code
}
func main() {
t := Contractor{}
process(&t) //why this line of code doesn't generate error
}
In Go some type and pointer to this time conform to the interface? So in my example t and &t are both Pullers?
From the Go spec:
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).
In your case the method set of &t (which is of type *Contractor) is the set of all methods declared with receiver *Contractor or Contractor, so it contains the method doSomething().
This is also discussed in the Go FAQ, and in Go code review comments. Finally, this is covered by many past Stack Overflow questions like this one or that one.

Anonymous/explicitly embedded a interface in struct

type A interface {
f()
}
type B struct {
A
}
type C struct {
Imp A
}
func main() {
b := B{}
c := C{}
//b can be directly assigned to the A interface, but c prompts that it cannot be assigned
var ab A = b
//Cannot use 'c' (type C) as type A in assignment Type does not implement 'A' as some methods are missing: f()
var ac A = c
}
what's the different between in the B struct and C struct?
in Go sheet
A field declared with a type but no explicit field name is called an embedded field. An embedded field must be specified as a type name T or as a pointer to a non-interface type name *T, and T itself may not be a pointer type. The unqualified type name acts as the field name.
If you continue reading the same section of the spec of the spec, you will notice the following:
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.
If S contains an embedded
field *T, the method sets of S and *S both include promoted methods
with receiver T or *T.
Your struct B has no methods explicitly defined on it, but B's method set implicitly includes the promoted methods from the embedded field. In this case, the embedded field is an interface with method f(). You can use any object that satisfies that interface and its f() method will automatically be part of the method set for B.
On the other hand, your C struct has a named field. The methods on Imp do not get automatically added to C's method set. Instead, to access the f() method from Imp, you would need to specifically call C.Imp.f().
Finally: the fact that you're using an interface as the (embedded or not) field does not matter, it could easily be another struct that has a f() method. The important part is whether f() becomes part of the parent struct's method set or not, which will allow it to implement A or not.

Do we have something same as Java and C# Object in Golang?

In Java and C#, the Object class is implicitly parent of all classes that are defined. Is there something similar in go?
There is no inheritance in Go.
I think you are looking for interface: Go: What's the meaning of interface{}?
but if you need something similar to Object (not Class) you may use interface:
Variables of interface type also have a distinct dynamic type, which
is the concrete type of the value assigned to the variable at run time
(unless the value is the predeclared identifier nil, which has no
type). The dynamic type may vary during execution but values stored in
interface variables are always assignable to the static type of the
variable.
var x interface{} // x is nil and has static type interface{}
var v *T // v has value nil, static type *T
x = 42 // x has value 42 and dynamic type int
x = v // x has value (*T)(nil) and dynamic type *T
and:
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. The value of an uninitialized variable of
interface type is nil.
see: http://golang.org/doc/go_spec.html

Interface fulfilled by struct embedding

I'm confused by my experiments with the following program, related to fulfilling interface with struct embedding, with named types and pointer receivers, respectively:
package main
import "fmt"
type MyInt interface {
mytest()
}
type Base struct {
}
func (b *Base) mytest() {
fmt.Println("From base")
}
type Derived struct {
Base
}
type Derived2 struct {
*Base
}
func main() {
// Only this one has problem
// However, if we change mytest's receiver from *Base to Base, all the four assignments are OK
var _ MyInt = Derived{}
// OK
var _ MyInt = &Derived{}
var _ MyInt = Derived2{}
var _ MyInt = &Derived2{}
}
See the comments in the code for my confusions. Are there any principal ways to explain them?
From the Go language specification:
Given a struct type S and a type named T, promoted methods are
included in the method set of the struct as follows:
If S contains an anonymous 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.
If S contains an anonymous
field *T, the method sets of S and *S both include promoted methods
with receiver T or *T.
The case that doesn't work in your code:
var _ MyInt = Derived{}
Here the method set of Derived (which contains an anonymous field Base) includes methods of Base by rule 1. Since mytest is a method of *Base and not Base, it's promoted to a method of *Derived (by the second rule), but not of Derived.
Why is it like that? Well, it's similar to the rule for method sets of structs: methods of T are also methods of T*, but not vice-versa. That's because a method of a pointer receiver can expect to be able to mutate its receiver, but a method of a non-pointer receiver can't.
As per your code function mytest can be called on receiver which pointer to Base.
Struct Derived inherits/embeds Base and Derived2 inherits/embeds *Base i.e. pointer to base.
For
var _MyInt = &Derived2{}: Here pointer of Derived2 is created and since Dervied2 inherits from *Base calling mytest on _MyInt will work
var _MyInt = Derived2{}: Instance of Derived2 is created and since Dervied2 inherits from *Base calling mytest on _MyInt will work
var _MyInt = &Derived{}: Here pointer of Derived is created and since Dervied inherits from Base calling mytest on _MyInt will work
var _MyInt = Derived{}: Instance of Derived is created and since Dervied inherits from Base calling mytest on _MyInt will not work has pointer to Base is expected.
You rightly pointed out that changing receiver from *Base to Base will work because Go will be able recognize Object from pointer and will be able to call mytest.
As per golang specification
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).
Hope this helps

Address of composite literal used as interface

The address of a composite literal is evaluated as the literal itself when used as an interface. Can somebody please point to the part of the ref spec which deals with this ?
package main
import "fmt"
type ntfc interface {
rx() int
}
type cncrt struct {
x int
}
func (c cncrt) rx() int{
return c.x
}
func rtrnsNtfca() ntfc {
return &cncrt{3}
}
func rtrnsNtfc() ntfc {
return cncrt{3}
}
func rtrnsCncrt() *cncrt {
return &cncrt{3}
}
func main() {
fmt.Println(rtrnsNtfca().rx())
fmt.Println(rtrnsNtfc().rx())
fmt.Println(rtrnsCncrt().rx())
}
Also here. For future ref., is it acceptable to just link to the playground without including the code here?
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).
So the method set of *cncrt includes the methods set of cncrt. Since rx() is an element of cncrt's method set, it will also be in *cncrt's method set. Which means both cncrt and *cncrt types implement the ntfc interface.
If you have a pointer value (*cncrt) and you call rx() on it, the pointer will automatically be dereferenced which will be the receiver of the rx() method.
In your rtnsNtfca() and rtnsNtfc() functions an interface value of ntfc will automatically be created and returned. Interface values in Go are represented as (type;value) pairs (for more details: The Laws of Reflection #The representation of an interface). So both rtnsNtfca() and rtnsNtfc() return an interface value, but the first one holds a dynamic value of type *cncrt and the latter one holds a dynamic value of type cncrt.
And your 3rd method rtrnsCncrt() returns a concrete type (*cncrt), there is no interface wrapping involved there.
Note: "The other way around"
Spec: Calls:
If x is addressable and &x's method set contains m, x.m() is shorthand for (&x).m().
This means if you would have declared rx() to have a pointer receiver, and you have a variable of type cncrt (note: not pointer), you could still call the rx() method on it if it is addressable, and the address would be taken automatically and used as the receiver.

Resources