golang的interface剖析
type MyInt int
var i int
var j MyInt
var r io.Reader
var r io.Reader
tty, err := os.OpenFile("/dev/tty", os.O_RDWR, 0)
if err != nil {
return nil, err
}
r = tty
到这里,r的类型是什么?r的类型仍然是interface io.Reader,只是r = tty这一句,隐含了一个类型转换,将tty转成了io.Reader。
type Binary uint64
func (i Binary) String() string {
return strconv.Uitob64(i.Get(), 2)
} func (i Binary) Get() uint64 {
return uint64(i)
}
.png)

var w io.Writer
switch v := any.(type) {
case int:
return strconv.Itoa(v)
case float:
return strconv.Ftoa(v, 'g', -1)
}
1 var any interface{} // initialized elsewhere
2 s := any.(Stringer) // dynamic conversion
3 for i := 0; i < 100; i++ {
4 fmt.Println(s.String())
5 }
143 type iface struct {
144 tab *itab // 指南itable
145 data unsafe.Pointer // 指向真实数据
146 }
617 type itab struct {
618 inter *interfacetype
619 _type *_type
620 link *itab
621 bad int32
622 unused int32
623 fun [1]uintptr // variable sized
624 }
310 type imethod struct {
311 name nameOff
312 ityp typeOff
313 }
314
315 type interfacetype struct {
316 typ _type
317 pkgpath name
318 mhdr []imethod
319 }
320
28 type _type struct {
29 size uintptr
30 ptrdata uintptr // size of memory prefix holding all pointers
31 hash uint32
32 tflag tflag
33 align uint8
34 fieldalign uint8
35 kind uint8
36 alg *typeAlg
37 // gcdata stores the GC type data for the garbage collector.
38 // If the KindGCProg bit is set in kind, gcdata is a GC program.
39 // Otherwise it is a ptrmask bitmap. See mbitmap.go for details.
40 gcdata *byte
41 str nameOff
42 ptrToThis typeOff
43 }
22 func itabhash(inter *interfacetype, typ *_type) uint32 {
23 // compiler has provided some good hash codes for us.
24 h := inter.typ.hash
25 h += 17 * typ.hash
26 // TODO(rsc): h += 23 * x.mhash ?
27 return h % hashSize
28 }
44 h := itabhash(inter, typ)
45
46 // look twice - once without lock, once with.
47 // common case will be no lock contention.
48 var m *itab
49 var locked int
50 for locked = 0; locked < 2; locked++ {
51 if locked != 0 {
52 lock(&ifaceLock)
53 }
54 for m = (*itab)(atomic.Loadp(unsafe.Pointer(&hash[h]))); m != nil; m = m.link {
55 if m.inter == inter && m._type == typ {
71 return m // 找到了前面计算过的itab
72 }
73 }
74 }
75 // 没有找到,生成一个,并加入到itab的hash中。
76 m = (*itab)(persistentalloc(unsafe.Sizeof(itab{})+uintptr(len(inter.mhdr)-1)*sys.PtrSize, 0, &memstats.other_sys))
77 m.inter = inter
78 m._type = typ
79 additab(m, true, canfail)
13 const (
14 hashSize = 1009
15 )
16
17 var (
18 ifaceLock mutex // lock for accessing hash
19 hash [hashSize]*itab
20 )
92 // both inter and typ have method sorted by name,
93 // and interface names are unique,
94 // so can iterate over both in lock step;
95 // the loop is O(ni+nt) not O(ni*nt). // 按name排序过的,因此这里的匹配只需要O(ni+nt)
99 j := 0
100 for k := 0; k < ni; k++ {
101 i := &inter.mhdr[k]
102 itype := inter.typ.typeOff(i.ityp)
103 name := inter.typ.nameOff(i.name)
104 iname := name.name()
109 for ; j < nt; j++ {
110 t := &xmhdr[j]
111 tname := typ.nameOff(t.name)
112 if typ.typeOff(t.mtyp) == itype && tname.name() == iname {
118 if m != nil {
119 ifn := typ.textOff(t.ifn)
120 *(*unsafe.Pointer)(add(unsafe.Pointer(&m.fun[0]), uintptr(k)*sys.PtrSize)) = ifn // 找到匹配,将实际类型的方法填入itab的fun
121 }
122 goto nextimethod
123 }
124 }
125 }
135 nextimethod:
136 }
140 h := itabhash(inter, typ) //插入上面的全局hash
141 m.link = hash[h]
142 atomicstorep(unsafe.Pointer(&hash[h]), unsafe.Pointer(m))
143 }
到这里,interface的数据结构的框架。
golang的interface剖析的更多相关文章
- Golang 源码剖析:log 标准库
Golang 源码剖析:log 标准库 原文地址:Golang 源码剖析:log 标准库 日志 输出 2018/09/28 20:03:08 EDDYCJY Blog... 构成 [日期]<空格 ...
- Golang的Interface是个什么鬼
问题概述 Golang的interface,和别的语言是不同的.它不需要显式的implements,只要某个struct实现了interface里的所有函数,编译器会自动认为它实现了这个interfa ...
- golang 关于 interface 的学习整理
Golang-interface(四 反射) go语言学习-reflect反射理解和简单使用 为什么在Go语言中要慎用interface{} golang将interface{}转换为struct g ...
- Golang 的 `[]interface{}` 类型
Golang 的 []interface{} 类型 我其实不太喜欢使用 Go 语言的 interface{} 类型,一般情况下我宁愿多写几个函数:XxxInt, XxxFloat, XxxString ...
- Golang接口(interface)三个特性(译文)
The Laws of Reflection 原文地址 第一次翻译文章,请各路人士多多指教! 类型和接口 因为映射建设在类型的基础之上,首先我们对类型进行全新的介绍. go是一个静态性语言,每个变量都 ...
- Golang-interface(四 反射)
github:https://github.com/ZhangzheBJUT/blog/blob/master/reflect.md 一 反射的规则 反射是程序执行时检查其所拥有的结构.尤其是类型的一 ...
- golang之interface
一.概述 接口类型是对 "其他类型行为" 的抽象和概况:因为接口类型不会和特定的实现细节绑定在一起:很多面向对象都有类似接口概念,但Golang语言中interface的独特之处在 ...
- golang将interface{}转换为struct
项目中需要用到golang的队列,container/list,需要放入的元素是struct,但是因为golang中list的设计,从list中取出时的类型为interface{},所以需要想办法把i ...
- Golang-interface(二 接口与nil)
github: https://github.com/ZhangzheBJUT/blog/blob/master/nil.md 一 接口与nil 前面解说了go语言中接口的基本用法,以下将说一说nil ...
随机推荐
- MFC入门(一)-- 第一个简单的windows图形化界面小程序(打开计算器,记事本,查IP)
////////////////////////////////序//////////////////////////////// 大约三年前,学过一些简单的编程语言之后其实一直挺苦恼于所写的程序总是 ...
- Sql Server插入数据并返回自增ID,@@IDENTITY,SCOPE_IDENTITY和IDENT_CURRENT的区别(转载)
预备知识:SQL Server的IDENTITY关键字IDENTITY关键字代表的是一个函数,而不是identity属性.在access里边没有这个函数,所以在access不能用这个语句.语法:ide ...
- C#中byte[]类型转换为其它类型
我们这里就举byte[]类型和long类型的转换,其它数据类型用BitConverter类以此类推: /// <summary> /// 字节数组转换为long类型 /// </su ...
- 开发手记:Linux下更改Oracle表空间大小
问题:同事反馈我们的测试环境数据库执行SQL和编译PKG非常慢,猜测可能是我们的测试环境数据库的表空间满了,但是我不知道数据库DBA的用户和密码. 步骤1:查看表空间占用情况 SELECT UPPER ...
- Luogu P4462 [CQOI2018]异或序列
一道稍微要点脑子的莫队题,原来省选也会搬CF原题 首先利用\(xor\)的性质,我们可以搞一个异或前缀和的东西 每一次插入一个数,考虑它和之前已经加入的数能产生多少贡献 记一下之前的异或总值,然后还是 ...
- C/C++中连接函数strcat的应用(简单讲解)
有位学弟问到我如何将两个字符连接起来,想想java/python里面可以直接用+连接起来,可是C/C++里面有没有这么方便的做法呢? 答案是有的,在C语言的string.h库中有个神奇的函数叫做str ...
- 分布式监控系统Zabbix-3.0.3--短信报警设置
前面已分别介绍了zabbix的邮件.微信报警设置,这些都是手机在有网络时才能收到报警信息,那如果手机没有网的情况下怎么办,这就需要考虑使用短信接口报警了.当服务出现故障达到预警级别是通过发送短信的形式 ...
- restfull环境搭建-helloword
原文地址:http://blog.csdn.net/u013158799/article/details/39758341 1. REST和RESTful Web Services的简要说明 REST ...
- 微信小程序中的组件
前言 之前做小程序开发的时候,对于开发来说比较头疼的莫过于自定义组件了,当时官方对这方面的文档也只是寥寥几句,一笔带过而已,所以写起来真的是非常非常痛苦!! 好在微信小程序的库从 1.6.3 开始,官 ...
- 求去掉一条边使最小割变小 HAOI2017 新型城市化
先求最小割,然后对残量网络跑Tarjan.对于所有满流的边,若其两端点不在同一个SCC中,则这条边是满足条件的. 证明见 来源:HAOI2017 新型城市化