假设我有以下类型定义:
type ICat interface {
Meow() string
}
type Cat struct {
Name string
}
func (c Cat) Meow() string {
return "Meow"
}
当我执行此操作时:
var a Cat
a.Name = "Tom"
在内存中分配 Cat 类型的结构,并为其分配一个字段。
但是,如果执行以下操作:
var b ICat
内存中到底分配了什么? Golang 接口只是一个包含指向另一个结构的指针的结构吗? “盒装指针”?.
接口包含两件事:指向底层数据的指针和该数据的类型。所以,当你声明
var b ICat
b
包含这两个元素。
当你这样做时:
b:=Cat{}
b
现在包含指向 Cat{}
副本的指针,并且数据是 struct Cat
。
当你这样做时:
b:=&Cat{}
b
现在包含指向 Cat{}
的指针的副本,并且事实上它是 *Cat
。
package main
import (
"fmt"
"reflect"
)
type Cat struct {
name string
}
func (c Cat) Meow() {
fmt.Println("I can meow")
}
type ICat interface {
Meow()
}
func main() {
fmt.Println("Hello, World!")
a := Cat{name: "Clara"}
a.Meow()
fmt.Printf("a = %v \t type(a) = %T \t &a = %p\n\n", a, a, &a)
var b ICat
b = a
introspectInterface("b", b)
var c ICat
c = &a
introspectInterface("c", c)
}
func introspectInterface(name string, i ICat) {
iType := reflect.TypeOf(i)
iValue := reflect.ValueOf(i)
fmt.Printf("Inside %s - type: %T \t concrete type: %v \t value: %v\n", name, i, iType, iValue)
if iValue.Kind() == reflect.Ptr {
ptrValue := iValue.Pointer()
fmt.Printf("%s points to address (as pointer): %p, pointing to value: %v\n", name, ptrValue, iValue.Elem().Interface())
fmt.Printf("%s points to the address of &a: %p\n", name, ptrValue)
}
fmt.Println()
}