• 芝士老爹
    2019-04-12
    课程源码:
    if reflect.TypeOf(st).Kind() != reflect.Ptr {
            // Elem() 获取指针指向的值
            if reflect.TypeOf(st).Elem().Kind() != reflect.Struct {
                return errors.New("the first param should be a pointer to the struct type.")
            }
        }
    这一段的判断有些疑问。
    第一行if先判断是否为指针,如果不是,则执行第二行if。
    但是第二行if里面用到了Elem()方法,这个方法不是指针是不能调用的。
    所以这里是不是有些问题?
    改成如下这样呢?
        if reflect.TypeOf(st).Kind() != reflect.Ptr {
            return errors.New("the first param should be a pointer")
        }
        // Elem() 获取指针指向的值
        if reflect.TypeOf(st).Elem().Kind() != reflect.Struct {
            return errors.New("the first param should be a pointer to the struct type")
        }
    请解惑、指正。
    展开

    作者回复: 非常感谢指出这个问题。你学得非常细致,正确的代码如下,github上的代码也会修正。

        if reflect.TypeOf(st).Kind() != reflect.Ptr {
            return errors.New("the first param should be a pointer to the struct type.")
        }
        // Elem() 获取指针指向的值
        if reflect.TypeOf(st).Elem().Kind() != reflect.Struct {
            return errors.New("the first param should be a pointer to the struct type.")
        }

    
     2
  • 西門熱
    2019-04-11
    老师您好。
    我看演示代码中多次出现reflect.TypeOf(st)和reflect.ValueOf(st),考虑到多次调用函数是否会存在性能问题,能否分别赋值给一个变量(新增变量占用内存?),例如:
            rt := reflect.TypeOf(st)
        rv := reflect.ValueOf(st)
    然后在下面rt.Kind(),rt.Elem().Kind()这样调用。

    作者回复: 可以啊。你还可以利用我们接先来课程中涉及的性能分析方法来分析一下影响。

    
     2
  • Geek_338030
    2019-09-22
    好像有点懂老师的意思了,我这样理解是否正确呢?
    (reflect.ValueOf(st)).Elem().FieldByName(k)
    返回的是一个struct filed类型的值
    (reflect.ValueOf(st)).Elem().Type().FieldByName(k)
    由于加上了Type,所以就返回了struct filed这个类型

    作者回复: Elem()返回的是值Value,而Type()之后返回的是类型。
    你运行以下两行代码就会清楚了:
    fmt.Println("--", (reflect.ValueOf(st)).Elem())
    fmt.Println("**", (reflect.ValueOf(st)).Elem().Type())

    
     1
  • Geek_338030
    2019-09-20
    (reflect.ValueOf(st)).Elem().Type().FieldByName(k)
    (reflect.ValueOf(st)).Elem().Type()打印出来的结果是flexible_reflect.Employee,而FieldByName这个函数返回的不是k对应的值吗?为什么返回的却是{Name string format:"normal" 16 [1] false} true

    作者回复: 以下是FieldByName的定义,可见返回值是StructField类型。
    // FieldByName returns the struct field with the given name
        // and a boolean indicating if the field was found.
        FieldByName(name string) (StructField, bool)

    // A StructField describes a single field in a struct.
    type StructField struct {
        // Name is the field name.
        Name string
        // PkgPath is the package path that qualifies a lower case (unexported)
        // field name. It is empty for upper case (exported) field names.
        // See https://golang.org/ref/spec#Uniqueness_of_identifiers
        PkgPath string

        Type Type // field type
        Tag StructTag // field tag string
        Offset uintptr // offset within struct, in bytes
        Index []int // index sequence for Type.FieldByIndex
        Anonymous bool // is an embedded field
    }

    
     1
  • Geek_338030
    2019-09-20

            if field.Type == reflect.TypeOf(v) {
                vstr := reflect.ValueOf(st)
                vstr = vstr.Elem()
                            //为什么这里查看我要修改的st的时候,会发现打印出两个值呢?
                            fmt.Println(st)
                vstr.FieldByName(k).Set(reflect.ValueOf(v))
            }
    显示结果如下:
    &{ 0}
    &{ Mike 0}

    展开

    作者回复: 因为传入的结构的实例里面包含两个field (Name和Age)所以重复了两遍,
    第一个输出是由于 Name和Age都还没有被赋值(Name位空字符串,Age为0,都是缺省值)
    第二个输出是由于Name已经被赋值了“Mike”

    
     1
  • Geek_338030
    2019-09-22
    麻烦老师了,但还是没太懂老师回复的,既然fieldByName return的是struct field和bool,那为什么以下的这一行代码返回的是一个k对应的值呢?
    (reflect.ValueOf(st)).Elem().FieldByName(k)
    而加上了Type,即:(reflect.ValueOf(st)).Elem().Type().FieldByName(k)
    返回的就变成了是struct field 和bool了
    这是为什么?

    展开
    
    
我们在线,来聊聊吧