Go is a statically-typed language, similar to Java and C#. However, one feature sets Go apart from these languages: the interface. To metaphorically describe it, an interface in Go acts like the shell of a clam: it wraps a value, and when you "open" the shell, you can access the value inside.
iface StructIn Go runtime, once you assign a value to a variable of interface type, the Go runtime wraps the value using the iface struct. Here's what the iface struct looks like:
type iface struct {
tab *itab
data unsafe.Pointer
}
This struct contains two main elements:
tab: A pointer to a type descriptor (itab)data: A pointer to the actual valueYou can check the iface implementation here.
itab StructTo further understand iface, let's explore the itab struct:
type itab struct {
inter *interfacetype
_type *_type
hash uint32 // copy of _type.hash. Used for type switches.
_ [4]byte
fun [1]uintptr // variable sized. fun[0]==0 means _type does not implement inter.
}
The itab struct has:
inter: Information about the interface itself_type: The actual type of the value, also known as the type descriptorAdditional information can be found in the itab implementation here.
Note: The length of
funappears to be 1, but this is actually a C-style memory optimization technique known as "flexible array member".
Let's look at a simple example:
package main
import "fmt"
type Shape interface {
Area() float64
}
type Circle struct {
radius float64
}
func (c Circle) Area() float64 {
return 3.14 * c.radius * c.radius
}
func main() {
var s Shape
s = Circle{5.0}
fmt.Println(s.Area())
}
In this code, a Circle type value is assigned to the interface-typed variable s. The Go runtime creates an iface struct, which includes an itab that has the Circle type information stored in its _type field. The fun field contains a pointer to an array of functions, which in this case is Area().
When s.Area() is called, the Go runtime dynamically dispatches the Area() function call through the interface s. It locates the pointer to the Area function and executes it.
글 재미있게 봤습니다.