我一直在阅读Go如何通过指针与值将函数传递给函数。我一直在阅读有关接口类型的信息。我一直在篡改反射包。但显然,由于此示例代码,我仍然不明白它是如何工作的:
package main
import (
"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个业务结构列表,其中包含Pizza 0到9的Business.Name。我理解在我的例子中,我的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
不同?
您的调试器很可能使用(或至少遵循)fmt
包的默认格式规则:
对于复合对象,使用这些规则打印元素,递归地,如下所示:
struct: {field0 field1 ...} array, slice: [elem0 elem1 ...] maps: map[key1:value1 key2:value2 ...] pointer to above: &{}, &[], &map[]
在你的第一个案例中,i
持有*[]Business
类型的值。因此,如果正在打印(或检查)的值是指向切片的指针,则将其打印为&[values]
。
在你的第二个案例中,i
持有一个指向interface{}
值的指针,该值为*interface{}
。打印此类型的值时,使用默认的%p
格式,它只是将内存地址打印为前缀为0x
的十六进制值。