What's the meaning of interface{}?
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, 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 aninterface{}
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{}) {
// ...
}
Here’s where it gets confusing:
inside of the
DoSomething
function, what isv
'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 ofinterface{}
type.When passing a value into the
DoSomething
function, the Go runtime will perform a type conversion (if necessary), and convert the value to aninterface{}
value.
All values have exactly one type at runtime, andv
's one static type isinterface{}
.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 forStringer
holding type Binary lists the methods used to satisfy Stringer, which is justString
: Binary's other methods (Get
) make no appearance in theitable
.The second word in the interface value points at the actual data, in this case a copy of
b
.
The assignmentvar s Stringer = b
makes a copy ofb
rather than point atb
for the same reason thatvar c uint64 = b
makes a copy: ifb
later changes,s
andc
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.
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
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.