当前位置: 首页 > news >正文

dedecms 调用网站名称wordpress 我爱水煮鱼

dedecms 调用网站名称,wordpress 我爱水煮鱼,重庆做营销型网站建设公司,网页特效源码网站文章目录 前言官方解释内存布局程序运行中的内存布局通用方法 前言 在 Go 中#xff0c;如果 interface{} 作为函数参数的话#xff0c;是可以传任意参数的#xff0c;然后通过类型断言来转换。 举个例子#xff1a; package mainimport fmtfunc foo(v inter… 文章目录 前言官方解释内存布局程序运行中的内存布局通用方法 前言 在 Go 中如果 interface{} 作为函数参数的话是可以传任意参数的然后通过类型断言来转换。 举个例子 package mainimport fmtfunc foo(v interface{}) {if v1, ok1 : v.(string); ok1 {fmt.Println(v1)} else if v2, ok2 : v.(int); ok2 {fmt.Println(v2)} }func main() {foo(233)foo(666) }不管是传 int 还是 string最终都能输出正确结果。 那么既然是这样的话我就有一个疑问了拿出我举一反三的能力。是否可以将 []T 转换为 []interface 呢 比如下面这段代码 func foo([]interface{}) { /* do something */ }func main() {var a []string []string{hello, world}foo(a) }很遗憾这段代码是不能编译通过的如果想直接通过 b : []interface{}(a) 的方式来转换还是会报错 cannot use a (type []string) as type []interface {} in function argument正确的转换方式需要这样写 b : make([]interface{}, len(a), len(a)) for i : range a {b[i] a[i] }本来一行代码就能搞定的事情却非要让人写四行是不是感觉很麻烦那为什么 Go 不支持呢我们接着往下看。 官方解释 这个问题在官方 Wiki 中是有回答的我复制出来放在下面 The first is that a variable with type []interface{} is not an interface! It is a slice whose element type happens to be interface{}. But even given this, one might say that the meaning is clear. Well, is it? A variable with type []interface{} has a specific memory layout, known at compile time. Each interface{} takes up two words (one word for the type of what is contained, the other word for either the contained data or a pointer to it). As a consequence, a slice with length N and with type []interface{} is backed by a chunk of data that is N2 words long. This is different than the chunk of data backing a slice with type []MyType and the same length. Its chunk of data will be Nsizeof(MyType) words long. The result is that you cannot quickly assign something of type []MyType to something of type []interface{}; the data behind them just look different. 大概意思就是说主要有两方面原因 []interface{} 类型并不是 interface它是一个切片只不过碰巧它的元素是 interface[]interface{} 是有特殊内存布局的跟 interface 不一样。 下面就来详细说说是怎么个不一样。 内存布局 首先来看看 slice 在内存中是如何存储的。在源码中它是这样定义的 // src/runtime/slice.gotype slice struct {array unsafe.Pointerlen intcap int }array 是指向底层数组的指针len 是切片的长度cap 是切片的容量也就是 array 数组的大小。 举个例子创建如下一个切片 is : []int64{0x55, 0x22, 0xab, 0x9}那么它的布局如下图所示 假设程序运行在 64 位的机器上那么每个「正方形」所占空间是 8 bytes。上图中的 ptr 所指向的底层数组占用空间就是 4 个「正方形」也就是 32 bytes。 接下来再看看 []interface{} 在内存中是什么样的。 回答这个问题之前先看一下 interface{} 的结构Go 中的接口类型分成两类 iface 表示包含方法的接口eface 表示不包含方法的空接口。 源码中的定义分别如下 type iface struct {tab *itabdata unsafe.Pointer }type eface struct {_type *_typedata unsafe.Pointer }具体细节我们不去深究但可以明确的是每个 interface{} 包含两个指针 会占据两个「正方形」。第一个指针指向 itab 或者 _type第二个指针指向实际的数据。 所以它在内存中的布局如下图所示 因此不能直接将 []int64 直接传给 []interface{}。 程序运行中的内存布局 接下来换一个更形象的方式从程序实际运行过程中看看内存的分布是怎么样的 看下面这样一段代码 package mainvar sum int64func addUpDirect(s []int64) {for i : 0; i len(s); i {sum s[i]} }func addUpViaInterface(s []interface{}) {for i : 0; i len(s); i {sum s[i].(int64)} }func main() {is : []int64{0x55, 0x22, 0xab, 0x9}addUpDirect(is)iis : make([]interface{}, len(is))for i : 0; i len(is); i {iis[i] is[i]}addUpViaInterface(iis) }我们使用 Delve 来进行调试可以点击这里进行安装。 dlv debug slice-layout.go Type help for list of commands. (dlv) break slice-layout.go:27 Breakpoint 1 set at 0x105a3fe for main.main() ./slice-layout.go:27 (dlv) cmain.main() ./slice-layout.go:27 (hits goroutine(1):1 total:1) (PC: 0x105a3fe)22: iis : make([]interface{}, len(is))23: for i : 0; i len(is); i {24: iis[i] is[i]25: }26:27: addUpViaInterface(iis)28: }打印 is 的地址 (dlv) p is (*[]int64)(0xc00003a740)接下来看看 slice 在内存中都包含了哪些内容 (dlv) x -fmt hex -len 32 0xc00003a740 0xc00003a740: 0x10 0xa7 0x03 0x00 0xc0 0x00 0x00 0x00 0xc00003a748: 0x04 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0xc00003a750: 0x04 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0xc00003a758: 0x00 0x00 0x09 0x00 0xc0 0x00 0x00 0x00每行有 8 个字节也就是上文说的一个「正方形」。第一行是指向数据的地址第二行是 4表示切片长度第三行也是 4表示切片容量。 再来看看指向的数据到底是怎么存的 (dlv) x -fmt hex -len 32 0xc00003a710 0xc00003a710: 0x55 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0xc00003a718: 0x22 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0xc00003a720: 0xab 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0xc00003a728: 0x09 0x00 0x00 0x00 0x00 0x00 0x00 0x00这就是一片连续的存储空间保存着实际数据。 接下来用同样的方式再来看看 iis 的内存布局。 (dlv) p iis (*[]interface {})(0xc00003a758) (dlv) x -fmt hex -len 32 0xc00003a758 0xc00003a758: 0x00 0x00 0x09 0x00 0xc0 0x00 0x00 0x00 0xc00003a760: 0x04 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0xc00003a768: 0x04 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0xc00003a770: 0xd0 0xa7 0x03 0x00 0xc0 0x00 0x00 0x00切片的布局和 is 是一样的主要的不同是所指向的数据 (dlv) x -fmt hex -len 64 0xc000090000 0xc000090000: 0x00 0xe4 0x05 0x01 0x00 0x00 0x00 0x00 0xc000090008: 0xa8 0xee 0x0a 0x01 0x00 0x00 0x00 0x00 0xc000090010: 0x00 0xe4 0x05 0x01 0x00 0x00 0x00 0x00 0xc000090018: 0x10 0xed 0x0a 0x01 0x00 0x00 0x00 0x00 0xc000090020: 0x00 0xe4 0x05 0x01 0x00 0x00 0x00 0x00 0xc000090028: 0x58 0xf1 0x0a 0x01 0x00 0x00 0x00 0x00 0xc000090030: 0x00 0xe4 0x05 0x01 0x00 0x00 0x00 0x00 0xc000090038: 0x48 0xec 0x0a 0x01 0x00 0x00 0x00 0x00仔细观察上面的数据偶数行内容都是相同的这个是 interface{} 的 itab 地址。奇数行内容是不同的指向实际的数据。 打印地址内容 (dlv) x -fmt hex -len 8 0x010aeea8 0x10aeea8: 0x55 0x00 0x00 0x00 0x00 0x00 0x00 0x00 (dlv) x -fmt hex -len 8 0x010aed10 0x10aed10: 0x22 0x00 0x00 0x00 0x00 0x00 0x00 0x00 (dlv) x -fmt hex -len 8 0x010af158 0x10af158: 0xab 0x00 0x00 0x00 0x00 0x00 0x00 0x00 (dlv) x -fmt hex -len 8 0x010aec48 0x10aec48: 0x09 0x00 0x00 0x00 0x00 0x00 0x00 0x00很明显通过打印程序运行中的状态和我们的理论分析是一致的。 通用方法 通过以上分析我们知道了不能转换的原因那有没有一个通用方法呢因为我实在是不想每次多写那几行代码。 也是有的用反射 reflect但是缺点也很明显效率会差一些不建议使用。 func InterfaceSlice(slice interface{}) []interface{} {s : reflect.ValueOf(slice)if s.Kind() ! reflect.Slice {panic(InterfaceSlice() given a non-slice type)}// Keep the distinction between nil and empty slice inputif s.IsNil() {return nil}ret : make([]interface{}, s.Len())for i : 0; i s.Len(); i {ret[i] s.Index(i).Interface()}return ret }还有其他方式吗答案就是 Go 1.18 支持的泛型这里就不过多介绍了大家有兴趣的话可以继续研究。
http://wiki.neutronadmin.com/news/415759/

相关文章:

  • 网站如何做微信支付百度网盘官网登陆入口
  • 建设互联网教育网站网页美工设计课程标准
  • 小学文化学网站开发怎么知道公司网站是哪个公司做的
  • 网站建设行业市场规模wordpress 用户验证
  • 网上购物有哪些网站?wordpress 循环菜单
  • 网站建设在国内外研究现状wordpress 表格小工具栏
  • 石家庄网站建设外贸做网站步骤
  • 做网站一定需要自己买主机吗百度指数网址是什么
  • 做网站美工 电脑配件要多大北京市企业信用信息查询网
  • 泊头建网站网站架构设计师工资
  • 手机端网站思路wordpress灯箱效果
  • 网站内容优化的主要方法广东省建设厅网站查询
  • 网站建设10个基本步骤微信自创小程序
  • wordpress+缩略图截图山西seo网站设计
  • 昆明免费网站制作海口官网设计公司
  • 网站建设的可行性报告怎么给网站做301
  • 如何把自己网站推广出去网站建设的面试要求
  • 海口网站设计建设适合装饰公司的名字
  • 企业网站源码 多语言南通精诚建设集团有限公司网站
  • 做期货的网站网站内链技巧
  • 网站开发 招标采购参数wordpress有人尝试登录
  • 成功案例 品牌网站百度seo外包
  • 橘子建站设计网名昵称
  • 南宁做网站比较好的公司建筑网站 知乎
  • 四川建设企业网站淮南做网站的
  • 有什么免费的网站收废铁的做网站有优点吗
  • 做网站的公司排行有必要自建网站做导购吗
  • 新东阳建设集团网站nodejs做视频网站
  • 网站开发 前端 后端最好的销售管理系统
  • 破天网站定制网站实名审核中心