为了账号安全,请及时绑定邮箱和手机立即绑定

混淆函数参数中的指针、切片和接口{}

混淆函数参数中的指针、切片和接口{}

Go
Helenr 2023-03-29 15:20:36
我一直在阅读有关 Go 如何通过指针与值将参数传递给函数的信息。我一直在阅读有关接口类型的信息。而且我一直在篡改反射包。但很明显,由于这里的示例代码,我仍然不明白它是如何工作的:package mainimport (  "reflect"  "fmt")type Business struct {  Name string}func DoSomething(b []Business) {  var i interface{}  i = &b  v := reflect.ValueOf(i).Elem()  for c:=0 ;c<10; c++ {    z := reflect.New(v.Type().Elem())    s := reflect.ValueOf(z.Interface()).Elem()    s.Field(0).SetString("Pizza Store "+ fmt.Sprintf("%v",c))    v.Set(reflect.Append(v, z.Elem()))  }  fmt.Println(b)}func main() {  business := []Business{}  DoSomething(business)}当我运行这段代码时,它将打印一个包含 10 个业务结构的列表,其中 Business.Name 为 Pizza 0 到 9。我知道在我的示例中,我的函数收到了业务切片的DoSomething副本,因此,business变量在我的主要功能中,无论做什么,都不会受到影响DoSomething。我接下来要做的是将我的更改func DoSomething(b []Business)为func DoSomething(b interface{}). 现在,当我尝试运行我的脚本时,出现panic: reflect: Elem of invalid type on在线运行时错误z := reflect.New(v.Type().Elem())我注意到DoSomething(b []Business), 变量i == &[]. 但是随着DoSomething(b interface{}),变量i == 0xc42000e1d0。i为什么在这两种情况下变量不同?
查看完整描述

1 回答

?
手掌心

TA贡献1942条经验 获得超3个赞

您的调试器很可能使用(或至少遵循)包的默认格式设置规则fmt:


对于复合对象,使用这些规则递归打印元素,布局如下:


struct:             {field0 field1 ...}

array, slice:       [elem0 elem1 ...]

maps:               map[key1:value1 key2:value2 ...]

pointer to above:   &{}, &[], &map[]

在您的第一种情况下,i它的值是 type *[]Business。因此,如果要打印(或检查)的值是指向切片的指针,则它会打印为&[values].


在你的第二种情况下,i持有一个指向一个值的指针interface{},它是 type *interface{}。打印这种类型的值时,%p使用默认格式,它只是将内存地址打印为前缀为 . 的十六进制值0x。


查看完整回答
反对 回复 2023-03-29
  • 1 回答
  • 0 关注
  • 112 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信