代码之家  ›  专栏  ›  技术社区  ›  learningtech

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

  •  1
  • learningtech  · 技术社区  · 6 年前

    我一直在读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)
    
    }
    

    DoSomething 函数收到了业务切片的副本,因此 business 主函数中的变量不受任何 剂量测定 做。

    我接下来做的就是改变我的生活 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 回复  |  直到 6 年前
        1
  •  2
  •   Community CDub    4 年前

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

    对于复合对象,元素将使用以下规则以递归方式打印,如下所示:

    struct:             {field0 field1 ...}
    array, slice:       [elem0 elem1 ...]
    maps:               map[key1:value1 key2:value2 ...]
    pointer to above:   &{}, &[], &map[]
    

    你的第一个案子 i 保存类型为的值 *[]Business . 因此,如果正在打印(或检查)的值是指向slice的指针,则将其打印为 &[values] .

    在你的第二个案子里 持有指向 interface{} 值的类型 *interface{} . 打印此类型的值时,默认值 %p 使用的格式只是将内存地址打印为前缀为的十六进制值 0x .