Visibility of embedded private interfaces in Go - go

If I embed an interface with a lowercase name (private) into another interface with an uppercase name (public), I assume that code outside of the defining package cannot see the embedded private interface. Is this assumption correct?
type b interface {
G() int
}
type A interface {
F() string
b
}
Code outside of the defining package cannot "see" the embedded b, correct? Outside code cannot call G through an instance of A.

Embedding unexported interface in interface
Interface embedding in interface is nothing more than merging the method set of the embedded interface into the embedder, so it becomes part of the method set of the embedder type. It doesn't matter if the embedded interface type is exported or not. Quoting from Spec: Interface types:
An interface T may use a (possibly qualified) interface type name E in place of a method specification. This is called embedding interface E in T; it adds all (exported and non-exported) methods of E to the interface T.
All that happens in your code is that A will be an interface with 2 methods: F() string and G() int. There won't be a "field" like A.b because A is an interface type, not a struct. So this isn't particularly "interesting".
How can you try it?
Create a folder subplay in any package, subplay.go:
package subplay
type b interface {
G() int
}
type A interface {
F() string
b
}
Create another go file that imports this subplay, e.g. play.go:
package main
import "play/subplay"
func main() {
var a subplay.A
a.G()
}
And it compiles. Runtime panic occurs though because a is not initialized (or rather left being nil), but if it would be, the a.G() call would not panic.
With the following additions there will be no run-time panic:
In subplay.go, add:
type aimpl struct{}
func (aimpl) F() string { return "aimpl.F() called" }
func (aimpl) G() int { return 1 }
func NewA() A {
return aimpl{}
}
And in play.go:
func main() {
var a subplay.A
a = subplay.NewA()
a.G()
}
The above code compiles and runs, and does not panic.
Also note that you can create a type in another package that implements subplay.A, you do not need to refer to subplay.b, because all that matters is the method set. The following another type also implements subplay.A, you can place this in play.go:
type another struct{}
func (another) F() string { return "aimpl.F() called" }
func (another) G() int { return 1 }
func main() {
var a subplay.A
a = another{}
a.G()
}
This again compiles and runs without run-time panic.
Embedding unexported interface in struct
A similar and more interesting case would be to embed an unexported struct (or an interface) type in a struct (and not in an interface), which "truly" creates an A.b field. Moreover, fields and methods of the embedded type get promoted to the embedder as if they would be fields or methods of the embedder. Quoting from Spec: Struct types:
A field or method f of an embedded field in a struct x is called promoted if x.f is a legal selector that denotes that field or method f.
Promoted fields act like ordinary fields of a struct except that they cannot be used as field names in composite literals of the struct.
Code outside of the defining package cannot refer to the embedded field A.b, this is correct, but code outside of the defining package can call the promoted A.G() method because this identifier is not lower-cased, so the restriction does not apply to it.
The restriction for non-exported identifiers is enforced by the compiler when you attempt to refer to them. Writing a.b.G() from another package is a compile-time error, because you are referring to a non-exported identifier (a.b). When you write a.G(), you are not referring to any non-exported identifiers, only to the exported a.G identifier, so it is allowed.

Related

Question regarding Golang interfaces and Composite struct [duplicate]

There are already several Q&As on this "X does not implement Y (... method has a pointer receiver)" thing, but to me, they seems to be talking about different things, and not applying to my specific case.
So, instead of making the question very specific, I'm making it broad and abstract -- Seems like there are several different cases that can make this error happen, can someone summary it up please?
I.e., how to avoid the problem, and if it occurs, what are the possibilities? Thx.
This compile-time error arises when you try to assign or pass (or convert) a concrete type to an interface type; and the type itself does not implement the interface, only a pointer to the type.
Short summary: An assignment to a variable of interface type is valid if the value being assigned implements the interface it is assigned to. It implements it if its method set is a superset of the interface. The method set of pointer types includes methods with both pointer and non-pointer receiver. The method set of non-pointer types only includes methods with non-pointer receiver.
Let's see an example:
type Stringer interface {
String() string
}
type MyType struct {
value string
}
func (m *MyType) String() string { return m.value }
The Stringer interface type has one method only: String(). Any value that is stored in an interface value Stringer must have this method. We also created a MyType, and we created a method MyType.String() with pointer receiver. This means the String() method is in the method set of the *MyType type, but not in that of MyType.
When we attempt to assign a value of MyType to a variable of type Stringer, we get the error in question:
m := MyType{value: "something"}
var s Stringer
s = m // cannot use m (type MyType) as type Stringer in assignment:
// MyType does not implement Stringer (String method has pointer receiver)
But everything is ok if we try to assign a value of type *MyType to Stringer:
s = &m
fmt.Println(s)
And we get the expected outcome (try it on the Go Playground):
something
So the requirements to get this compile-time error:
A value of non-pointer concrete type being assigned (or passed or converted)
An interface type being assigned to (or passed to, or converted to)
The concrete type has the required method of the interface, but with a pointer receiver
Possibilities to resolve the issue:
A pointer to the value must be used, whose method set will include the method with the pointer receiver
Or the receiver type must be changed to non-pointer, so the method set of the non-pointer concrete type will also contain the method (and thus satisfy the interface). This may or may not be viable, as if the method has to modify the value, a non-pointer receiver is not an option.
Structs and embedding
When using structs and embedding, often it's not "you" that implement an interface (provide a method implementation), but a type you embed in your struct. Like in this example:
type MyType2 struct {
MyType
}
m := MyType{value: "something"}
m2 := MyType2{MyType: m}
var s Stringer
s = m2 // Compile-time error again
Again, compile-time error, because the method set of MyType2 does not contain the String() method of the embedded MyType, only the method set of *MyType2, so the following works (try it on the Go Playground):
var s Stringer
s = &m2
We can also make it work, if we embed *MyType and using only a non-pointer MyType2 (try it on the Go Playground):
type MyType2 struct {
*MyType
}
m := MyType{value: "something"}
m2 := MyType2{MyType: &m}
var s Stringer
s = m2
Also, whatever we embed (either MyType or *MyType), if we use a pointer *MyType2, it will always work (try it on the Go Playground):
type MyType2 struct {
*MyType
}
m := MyType{value: "something"}
m2 := MyType2{MyType: &m}
var s Stringer
s = &m2
Relevant section from the spec (from section Struct types):
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.
So in other words: if we embed a non-pointer type, the method set of the non-pointer embedder only gets the methods with non-pointer receivers (from the embedded type).
If we embed a pointer type, the method set of the non-pointer embedder gets methods with both pointer and non-pointer receivers (from the embedded type).
If we use a pointer value to the embedder, regardless of whether the embedded type is pointer or not, the method set of the pointer to the embedder always gets methods with both the pointer and non-pointer receivers (from the embedded type).
Note:
There is a very similar case, namely when you have an interface value which wraps a value of MyType, and you try to type assert another interface value from it, Stringer. In this case the assertion will not hold for the reasons described above, but we get a slightly different runtime-error:
m := MyType{value: "something"}
var i interface{} = m
fmt.Println(i.(Stringer))
Runtime panic (try it on the Go Playground):
panic: interface conversion: main.MyType is not main.Stringer:
missing method String
Attempting to convert instead of type assert, we get the compile-time error we're talking about:
m := MyType{value: "something"}
fmt.Println(Stringer(m))
To keep it short and simple, let say you have a Loader interface and a WebLoader that implements this interface.
package main
import "fmt"
// Loader defines a content loader
type Loader interface {
load(src string) string
}
// WebLoader is a web content loader
type WebLoader struct{}
// load loads the content of a page
func (w *WebLoader) load(src string) string {
return fmt.Sprintf("I loaded this page %s", src)
}
func main() {
webLoader := WebLoader{}
loadContent(webLoader)
}
func loadContent(loader Loader) {
loader.load("google.com")
}
The above code will give you this compile time error
./main.go:20:13: cannot use webLoader (type WebLoader) as type Loader
in argument to loadContent:
WebLoader does not implement Loader (Load method has pointer receiver)
To fix it you only need to change webLoader := WebLoader{} to following:
webLoader := &WebLoader{}
Why this will fix the issue? Because you defined this function func (w *WebLoader) Load to accept a pointer receiver. For more explanation please read #icza and #karora answers
Another case when I have seen this kind of thing happening is if I want to create an interface where some methods will modify an internal value and others will not.
type GetterSetter interface {
GetVal() int
SetVal(x int) int
}
Something that then implements this interface could be like:
type MyTypeA struct {
a int
}
func (m MyTypeA) GetVal() int {
return a
}
func (m *MyTypeA) SetVal(newVal int) int {
int oldVal = m.a
m.a = newVal
return oldVal
}
So the implementing type will likely have some methods which are pointer receivers and some which are not and since I have quite a variety of these various things that are GetterSetters I'd like to check in my tests that they are all doing the expected.
If I were to do something like this:
myTypeInstance := MyType{ 7 }
... maybe some code doing other stuff ...
var f interface{} = myTypeInstance
_, ok := f.(GetterSetter)
if !ok {
t.Fail()
}
Then I won't get the aforementioned "X does not implement Y (Z method has pointer receiver)" error (since it is a compile-time error) but I will have a bad day chasing down exactly why my test is failing...
Instead I have to make sure I do the type check using a pointer, such as:
var f interface{} = new(&MyTypeA)
...
Or:
myTypeInstance := MyType{ 7 }
var f interface{} = &myTypeInstance
...
Then all is happy with the tests!
But wait! In my code, perhaps I have methods which accept a GetterSetter somewhere:
func SomeStuff(g GetterSetter, x int) int {
if x > 10 {
return g.GetVal() + 1
}
return g.GetVal()
}
If I call these methods from inside another type method, this will generate the error:
func (m MyTypeA) OtherThing(x int) {
SomeStuff(m, x)
}
Either of the following calls will work:
func (m *MyTypeA) OtherThing(x int) {
SomeStuff(m, x)
}
func (m MyTypeA) OtherThing(x int) {
SomeStuff(&m, x)
}
Extend from above answers (Thanks for all of your answers)
I think it would be more instinctive to show all the methods of pointer / non pointer struct.
Here is the playground code.
https://play.golang.org/p/jkYrqF4KyIf
To summarize all the example.
Pointer struct type would include all non pointer / pointer receiver methods
Non pointer struct type would only include non pointer receiver methods.
For embedded struct
non pointer outer struct + non pointer embedded struct => only non pointer receiver methods.
non pointer outer struct + pointer embedded struct / pointer outer struct + non pointer embedded struct / pointer outer struct + pointer embedded struct => all embedded methods

Are interfaces only ever implemented by struct data types in Go?

I'm quite new to Go and was looking at Interfaces and their implementations.
All examples I have encountered use struct{} to implement any interface.
Is it possible to use any basic type?
The Go Programming Language Specification
Method declarations
A method is a function with a receiver. A method declaration binds an
identifier, the method name, to a method, and associates the method
with the receiver's base type.
The receiver is specified via an extra parameter section preceding the
method name. That parameter section must declare a single non-variadic
parameter, the receiver. Its type must be of the form T or *T
(possibly using parentheses) where T is a type name. The type denoted
by T is called the receiver base type; it must not be a pointer or
interface type and it must be defined in the same package as the
method. The method is said to be bound to the base type and the method
name is visible only within selectors for type T or *T.
No. It can be any type other than a pointer or interface type.
For example, using string as the underlying type,
package main
import (
"fmt"
"strings"
)
type Caser interface {
Upper() string
Lower() string
}
type Str string
func (s Str) Upper() string {
return strings.ToUpper(string(s))
}
func (s Str) Lower() string {
return strings.ToLower(string(s))
}
func main() {
str := Str("Forty-Two")
fmt.Println(str)
up := str.Upper()
fmt.Println(up)
lo := str.Lower()
fmt.Println(lo)
}
Playground: https://play.golang.org/p/9RDRTftqWot
Output:
Forty-Two
FORTY-TWO
forty-two

golang interface that depends on interface

I am not sure if these should be two separate questions or one, but it seems to me as one question of two parts - How go interfaces are supposed to be used? I have this two struggles:
The methods of the interfaces are globally scoped: If I have interface A and interface B that both implement the same method Foo, but with different arguments or return types I am unable to implement both at the same time from the same type. For example, I have GetBytes() method in one interface having return type []byte and in another ([]byte, error) How I should overcome this issue?
Another issue I have is when I try to define interface say interface A that has a method that returns interface B that is defined in the same layer. Now if I want to create an object that implements A, if I return struct that implements B go is not smart enough to deduce that this method implements the method in A and it forces me to create dependency on B. This seems to completely defeat the point of the way interfaces work in go at first place. How can I avoid this issue?
for example, if I have:
type B interface {
Bar()
}
type A interface {
Foo() B
}
for the following structs :
type b_impl struct{}
func (b b_impl) Bar() {}
type a_impl struct{}
A foo method
func (a a_impl) Foo() b_impl {}
does not satisfy the interface A and I need to make it:
func (a a_impl) Foo() B {}
which makes a dependency to the package where B is declared.
1st question:
In go you need to make different function names, when you want to do different tasks. Let's look into the standard library at the strconv package how things are solved there: https://golang.org/pkg/strconv/#pkg-index
Look to the different declaration of the append function there. There are functions for every different type.
So if you expect a FooInt funtion your interface should be also a FooInter, ...
2nd question:As a small example. You don't need to import the whole io package, when you want to use the io.Writer interface. It is totaly ok to copy the Writer declaration into your own package. If you do that correct, every io.Writer implementation will automatically implement your own Writer interface.
After reading the other comments maybe you have a different situation:
Let's say there is a package a and b with the interface a.A and b.B. If there is the situation that:
type A interface{
Foo() b.B
}
and you have to write an implementation for a.A, then you need to import package b. But that makes your binaries not bigger, because you will always need to import package a, which depends on b.
For implementing an interface, you need to have exactly the same method name and signature. Means the signature must be with the same types.
As much as it seems weird, these two don't have the same signature:
Foo() B
Foo() b_impl {}
It doesn't matter that b_impl implements B.
To overcome the need to import the package B is declared in, you can use anonymous type. This way the compiler won't require a specific type for the method signature.
type A interface {
Foo() interface{Bar()}
}
Which also can be written as embedding B:
type A interface {
Foo() interface{B}
}
Still, a_impl must have same signature, so it also needs to return an anonymous interface. You can also declare the same B interface in the package of a_impl, and embed it in an anonymous interface.
package impl
type B interface {
Bar()
}
type b_impl struct{}
func (b b_impl) Bar() {}
type a_impl struct{}
func (a a_impl) Foo() interface{B} {
return b_impl{}
}
I don't know if it's a bad practice or not, probably there are cases which redesign is required instead of doing this.

Is it necessary to use a type assertion to access the values of a type returned by interface?

When I have a function that returns an interface type, the returned value doesn't work as I would expect. That is, it acts strictly as the defined interface, and to access the methods and values not defined in the interface, I have to do a type assertion. Why?
Consider the following sample code:
package main
import (
"fmt"
)
type Frobnicator interface {
Frobnicate()
}
type Foo struct {
Value string
}
func (f *Foo) Frobnicate() {
fmt.Printf("The value is %s\n", f.Value)
}
func fooFactory () Frobnicator {
return &Foo{"chicken"}
}
func main() {
foo := fooFactory( )
foo.Frobnicate()
// foo.Value undefined (type Frobnicator has no field or method Value)
// fmt.Printf("foo value = %s\n", foo.Value)
bar := foo.(*Foo)
fmt.Printf("bar value = %s\n", bar.Value)
}
Is there a better, easier, more idiomatic way to get at foo.Value? Or is a type assertion really the best way?
Not sure what to answer here. Maybe there is a misconception what interface types are. Interface types are absolutely normal types. And you can do with a interface value what the interface says: Invoke the interface methods. For a struct type you may access fields and invoke interface methods as defined by the struct type. So everything is plain and simple: A type allows what it allows, no matter whether interface or struct.
It now happens that a value of interface type may contain some struct value (say). Up to now this is hidden. Type asserting reveals the struct value (and there is no more interface). You may hide an other struct value in the interface (given it implements the right methods) this might not have a Value field. This makes it clear that you cannot access the Value field without a type assertion, because it might not be there.
If you need access to inner value of interface implementation (Value), you must either expose it via interface itself or do a type assertion. That's because nothing in Frobnicator suggests whether it's Foo or some other implementing struct.
It is not different than many other languages. In Java you will have to cast also under similar circumstances.

What's the meaning of interface{}?

I'm new to interfaces and trying to do SOAP request by github
I don't understand the meaning of
Msg interface{}
in this code:
type Envelope struct {
Body `xml:"soap:"`
}
type Body struct {
Msg interface{}
}
I've observed the same syntax in
fmt.Println
but don't understand what's being achieved by
interface{}
Note: Go 1.18 (Q1 2022) does rename interface{} to any (alias for interface{}).
See issue 49884, CL 368254 and commit 2580d0e.
See the last part of this answer.
You can refer to the article "How to use interfaces in Go" (based on "Russ Cox’s description of interfaces"):
What is an interface?
An interface is two things:
it is a set of methods,
but it is also a type
The interface{} type (or any with Go 1.18+), the empty interface is the interface that has no methods.
Since there is no implements keyword, all types implement at least zero methods, and satisfying an interface is done automatically, all types satisfy the empty interface.
That means that if you write a function that takes an interface{} value as a parameter, you can supply that function with any value.
(That is what Msg represents in your question: any value)
func DoSomething(v interface{}) {
// ...
}
func DoSomething(v any) {
// ...
}
Here’s where it gets confusing:
inside of the DoSomething function, what is v's type?
Beginner gophers are led to believe that “v is of any type”, but that is wrong.
v is not of any type; it is of interface{} type.
When passing a value into the DoSomething function, the Go runtime will perform a type conversion (if necessary), and convert the value to an interface{} value.
All values have exactly one type at runtime, and v's one static type is interface{} (or any with Go 1.18+).
An interface value is constructed of two words of data:
one word is used to point to a method table for the value’s underlying type,
and the other word is used to point to the actual data being held by that value.
Addendum: This is were Russ's article is quite complete regarding an interface structure:
type Stringer interface {
String() string
}
Interface values are represented as a two-word pair giving a pointer to information about the type stored in the interface and a pointer to the associated data.
Assigning b to an interface value of type Stringer sets both words of the interface value.
The first word in the interface value points at what I call an interface table or itable (pronounced i-table; in the runtime sources, the C implementation name is Itab).
The itable begins with some metadata about the types involved and then becomes a list of function pointers.
Note that the itable corresponds to the interface type, not the dynamic type.
In terms of our example, the itable for Stringer holding type Binary lists the methods used to satisfy Stringer, which is just String: Binary's other methods (Get) make no appearance in the itable.
The second word in the interface value points at the actual data, in this case a copy of b.
The assignment var s Stringer = b makes a copy of b rather than point at b for the same reason that var c uint64 = b makes a copy: if b later changes, s and c are supposed to have the original value, not the new one.
Values stored in interfaces might be arbitrarily large, but only one word is dedicated to holding the value in the interface structure, so the assignment allocates a chunk of memory on the heap and records the pointer in the one-word slot.
Issue 33232 seems to point out to any as an alias to interface{} in Go 1.18 (Q1 2022)
Russ Cox explains:
'any' being only for constraints is a detail that will be in every writeup of generics - books, blog posts, and so on.
If we think we are likely to allow it eventually, it makes sense to allow it from the start and avoid invalidating all that written material.
'any' being only for constraints is an unexpected cut-out that reduces generality and orthogonality of concepts.
It's easy to say "let's just wait and see", but prescribing uses tends to create much more jagged features than full generality. We saw this with type aliases as well (and resisted almost all the proposed cut-outs, thankfully).
If 'any' is allowed in generics but not non-generic code, then it might encourage people to overuse generics simply because 'any' is nicer to write than 'interface{}', when the decision about generics or not should really be made by considering other factors.
If we allow 'any' for ordinary non-generic usage too, then seeing interface{} in code could serve as a kind of signal that the code predates generics and has not yet been reconsidered in the post-generics world.
Some code using interface{} should use generics. Other code should continue to use interfaces.
Rewriting it one way or another to remove the text 'interface{}' would give people a clear way to see what they'd updated and hadn't. (Of course, some code that might be better with generics must still use interface{} for backwards-compatibility reasons, but it can still be updated to confirm that the decision was considered and made.)
That thread also includes an explanation about interface{}:
It's not a special design, but a logical consequence of Go's type declaration syntax.
You can use anonymous interfaces with more than zero methods:
func f(a interface{Foo(); Bar()}) {
a.Foo()
a.Bar()
}
Analogous to how you can use anonymous structs anywhere a type is expected:
func f(a struct{Foo int; Bar string}) {
fmt.Println(a.Foo)
fmt.Println(a.Bar)
}
An empty interface just happens to match all types because all types have at least zero methods.
Removing interface{} would mean removing all interface functionality from the language if you want to stay consistent / don't want to introduce a special case.
interface{} means you can put value of any type, including your own custom type. All types in Go satisfy an empty interface (interface{} is an empty interface).
In your example, Msg field can have value of any type.
Example:
package main
import (
"fmt"
)
type Body struct {
Msg interface{}
}
func main() {
b := Body{}
b.Msg = "5"
fmt.Printf("%#v %T \n", b.Msg, b.Msg) // Output: "5" string
b.Msg = 5
fmt.Printf("%#v %T", b.Msg, b.Msg) //Output: 5 int
}
Go Playground
There are already good answers here. Let me add my own too for others who want to understand it intuitively:
Interface
Here's an interface with one method:
type Runner interface {
Run()
}
So any type that has a Run() method satisfies the Runner interface:
type Program struct {
/* fields */
}
func (p Program) Run() {
/* running */
}
func (p Program) Stop() {
/* stopping */
}
Although the Program type has also a Stop method, it still satisfies the Runner interface because all that is needed is to have all of the methods of an interface to satisfy it.
So, it has a Run method and it satisfies the Runner interface.
Empty Interface
Here's a named empty interface without any methods:
type Empty interface {
/* it has no methods */
}
So any type satisfies this interface. Because, no method is needed to satisfy this interface. For example:
// Because, Empty interface has no methods, following types satisfy the Empty interface
var a Empty
a = 5
a = 6.5
a = "hello"
But, does the Program type above satisfy it? Yes:
a = Program{} // ok
interface{} is equal to the Empty interface above.
var b interface{}
// true: a == b
b = a
b = 9
b = "bye"
As you see, there's nothing mysterious about it but it's very easy to abuse. Stay away from it as much as you can.
https://play.golang.org/p/A-vwTddWJ7G
It's called the empty interface and is implemented by all types, which means you can put anything in the Msg field.
Example :
body := Body{3}
fmt.Printf("%#v\n", body) // -> main.Body{Msg:3}
body = Body{"anything"}
fmt.Printf("%#v\n", body) // -> main.Body{Msg:"anything"}
body = Body{body}
fmt.Printf("%#v\n", body) // -> main.Body{Msg:main.Body{Msg:"anything"}}
This is the logical extension of the fact that a type implements an interface as soon as it has all methods of the interface.
From the Golang Specifications:
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.
A type implements any interface comprising any subset of its methods
and may therefore implement several distinct interfaces. For instance,
all types implement the empty interface:
interface{}
The concepts to graps are:
Everything has a Type. You can define a new type, let's call it T. Let's say now our Type T has 3 methods: A, B, C.
The set of methods specified for a type is called the "interface type". Let's call it in our example: T_interface. Is equal to T_interface = (A, B, C)
You can create an "interface type" by defining the signature of the methods. MyInterface = (A, )
When you specify a variable of type, "interface type", you can assign to it only types which have an interface that is a superset of your interface.
That means that all the methods contained in MyInterface have to be contained inside T_interface
You can deduce that all the "interface types" of all the types are a superset of the empty interface.
An example that extends the excellent answer by #VonC and the comment by #NickCraig-Wood. interface{} can point to anything and you need a cast/type assertion to use it.
package main
import (
. "fmt"
"strconv"
)
var c = cat("Fish")
var d = dog("Bone")
func main() {
var i interface{} = c
switch i.(type) {
case cat:
c.Eat() // Fish
}
i = d
switch i.(type) {
case dog:
d.Eat() // Bone
}
i = "4.3"
Printf("%T %v\n", i, i) // string 4.3
s, _ := i.(string) // type assertion
f, _ := strconv.ParseFloat(s, 64)
n := int(f) // type conversion
Printf("%T %v\n", n, n) // int 4
}
type cat string
type dog string
func (c cat) Eat() { Println(c) }
func (d dog) Eat() { Println(d) }
i is a variable of an empty interface with a value cat("Fish"). It is legal to create a method value from a value of interface type. See https://golang.org/ref/spec#Interface_types.
A type switch confirms i interface type is cat("Fish") . See https://golang.org/doc/effective_go.html#type_switch. i is then reassigned to dog("Bone"). A type switch confirms that i interface’s type has changed to dog("Bone") .
You can also ask the compiler to check that the type T implements the interface I by attempting an assignment: var _ I = T{}. See https://golang.org/doc/faq#guarantee_satisfies_interface and https://stackoverflow.com/a/60663003/12817546.
All types implement the empty interface interface{}. See https://talks.golang.org/2012/goforc.slide#44 and https://golang.org/ref/spec#Interface_types . In this example, i is reassigned, this time to a string "4.3".i is then assigned to a new string variable s with i.(string) before s is converted to a float64 type f using strconv. Finally f is converted to n an int type equal to 4. See What is the difference between type conversion and type assertion?
Go's built-in maps and slices, plus the ability to use the empty interface to construct containers (with explicit unboxing) mean in many cases it is possible to write code that does what generics would enable, if less smoothly. See https://golang.org/doc/faq#generics.
Interface is a type which is unknown at compile time
It is a contract between object and the struct type to satisfy with common functionality
or
common functionality acting on different types of struct objects
for example in the below code PrintDetails is a common functionality acting on different types of structs as Engineer,Manager,
Seniorhead
please find the example code
interface examplehttps://play.golang.org/p/QnAqEYGiiF7
A method can bind to any type(int, string, pointer, and so on) in GO
Interface is a way of declear what method one type should have, as long as A type has implement those methods, this can be assigned to this interface.
Interface{} just has no declear of method, so it can accept any type

Resources