浅谈Golang接口interface

简介: 浅谈Golang接口interface

前言

关于接口的底层原理剖析点击Golang底层原理剖析之类型系统,接口与类型断言


interface

  1. interface的两种类型 - 数据结构的interface,侧重于类型;面向对象中接口定义的interface,侧重于方法的声明
  2. 了解interface的底层定义 - eface和iface,都分为两个部分:类型与数据
  3. iface底层对类型匹配进行了优化 - map+mutex组合


源码

package main
import (
  "fmt"
)
type Dog interface {
  Hi()
}
type Dog1 struct{}
func (d Dog1) Hi() {}
type Dog2 struct{}
func (d Dog2) Hi() {}
/*
  查看汇编,了解调用:
1. go build -gcflags '-l' -o if main.go interface.go
2. go tool objdump -s "main\.dataInterface" if
(汇编会因平台不同,调用结果会不一样)调用了 CALL runtime.XXX
对应代码在runtime/iface.go下,在这里,我们看到了interface的两个核心结构 eface 和 iface,分别对应convT2E和convT2I
type iface struct {
  tab  *itab
  data unsafe.Pointer
}
type eface struct {
  _type *_type
  data  unsafe.Pointer
}
其中data指向了具体保存数据的内存地址,为一个通用结构。而itab中嵌套了_type,比较复杂,我们先从简单的eface看起
*/
func dataInterface() {
  var i interface{} = 1
  fmt.Println(i)
  // Tip: 类型定义,除非是100%确定成功,否则尽量用两个参数,否则会导致panic
  v, ok := i.(string)
  fmt.Printf(v, ok)
  var d1 Dog1
  var d2 Dog2
  var dList = []Dog{d1, d2}
  for _, v := range dList {
    v.Hi()
  }
}
/*
Tip: eface part,静态的数据结构
type _type struct {
  size       uintptr
  ptrdata    uintptr // size of memory prefix holding all pointers
  hash       uint32
  tflag      tflag
  align      uint8
  fieldAlign uint8
  kind       uint8
  // function for comparing objects of this type
  // (ptr to object A, ptr to object B) -> ==?
  equal func(unsafe.Pointer, unsafe.Pointer) bool
  // gcdata stores the GC type data for the garbage collector.
  // If the KindGCProg bit is set in kind, gcdata is a GC program.
  // Otherwise it is a ptrmask bitmap. See mbitmap.go for details.
  gcdata    *byte
  str       nameOff
  ptrToThis typeOff
}
Tip: runtime/type.go 类型定义包含了go语言常见的类型,我们可以从 t.kind & kindMask 看到Go里支持的所有类型
*/
/*
Tip: iface part,面向对象中的interface
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.
}
Tip: interfacetype 为接口的定义方法集; _type保存了具体的类型;而具体的方法的地址都被保存在fun中,是一个数组
type interfacetype struct {
  typ     _type
  pkgpath name
  mhdr    []imethod
}
type imethod struct {
  name nameOff
  ityp typeOff
}
methods := (*[1 << 16]unsafe.Pointer)(unsafe.Pointer(&m.fun[0]))[:ni:ni]
Tip: interface的类型推断,依赖于一个 itabTable,即一个map+lock,将匹配成功的保存进来,下次可直接查询
*/


目录
相关文章
|
5天前
|
JSON Go 数据格式
【Golang】解决使用interface{}解析json数字会变成科学计数法的问题
【2月更文挑战第9天】解决使用interface{}解析json数字会变成科学计数法的问题
59 0
|
5天前
|
JSON Go 数据格式
golang学习7,glang的web的restful接口结构体传参
golang学习7,glang的web的restful接口结构体传参
|
5天前
|
JSON Go 数据格式
golang学习6,glang的web的restful接口传参
golang学习6,glang的web的restful接口传参
|
5天前
|
JSON Go 数据格式
golang学习5,glang的web的restful接口
golang学习5,glang的web的restful接口
|
5天前
|
Go
golang学习4,glang的web接口
golang学习4,glang的web接口
|
5天前
|
安全 Go
Golang深入浅出之-接口(Interfaces)详解:抽象、实现与空接口
【4月更文挑战第22天】Go语言接口提供抽象能力,允许类型在不暴露实现细节的情况下遵循行为约定。接口定义了一组方法签名,类型实现这些方法即实现接口,无需显式声明。接口实现是隐式的,通过确保类型具有接口所需方法来实现。空接口`interface{}`接受所有类型,常用于处理任意类型值。然而,滥用空接口可能丧失类型安全性。理解接口、隐式实现和空接口的使用能帮助编写更健壮的代码。正确使用避免方法,如确保方法签名匹配、检查接口实现和谨慎处理空接口,是关键。
23 1
|
5天前
|
XML Go 数据格式
【微信公众号开发】基于golang的公众号开发——接入消息自动回复接口
【微信公众号开发】基于golang的公众号开发——接入消息自动回复接口
168 0
|
5天前
|
存储 缓存 Go
Golang底层原理剖析之类型系统,接口与类型断言
Golang底层原理剖析之类型系统,接口与类型断言
54 2
|
5天前
|
Go
用golang实现一个基于interface的多态示例,展示其使用场景和优劣性。
用golang实现一个基于interface的多态示例,展示其使用场景和优劣性。
|
6月前
|
运维 监控 应用服务中间件
用 Golang 采集 Nginx 接口流量大小
用 Golang 采集 Nginx 接口流量大小
http://www.vxiaotou.com