下载APP
登录
关闭
讲堂
算法训练营
Python 进阶训练营
企业服务
极客商城
客户端下载
兑换中心
渠道合作
推荐作者
当前播放: 39 | 万能程序
00:00 / 00:00
标清
  • 标清
1.0x
  • 2.0x
  • 1.5x
  • 1.25x
  • 1.0x
  • 0.5x
网页全屏
全屏
00:00
付费课程,可试看

Go语言从入门到实战

共55讲 · 55课时,约700分钟
6129
免费
01 | Go语言课程介绍
免费
02 | 内容综述
免费
03 | Go语言简介:历史背景、发...
免费
04 | 编写第一个Go程序
免费
05 | 变量、常量以及与其他语言...
06 | 数据类型
07 | 运算符
08 | 条件和循环
09 | 数组和切片
10 | Map声明、元素访问及遍历
11 | Map与工厂模式,在Go语言...
12 | 字符串
13 | Go语言的函数
14 | 可变参数和defer
15 | 行为的定义和实现
16 | Go语言的相关接口
17 | 扩展与复用
18 | 不一样的接口类型,一样的...
19 | 编写好的错误处理
20 | panic和recover
21 | 构建可复用的模块(包)
22 | 依赖管理
23 | 协程机制
24 | 共享内存并发机制
25 | CSP并发机制
26 | 多路选择和超时
27 | channel的关闭和广播
28 | 任务的取消
29 | Context与任务取消
30 | 只运行一次
31 | 仅需任意任务完成
32 | 所有任务完成
33 | 对象池
34 | sync.pool对象缓存
35 | 单元测试
36 | Benchmark
37 | BDD
38 | 反射编程
39 | 万能程序
40 | 不安全编程
41 | 实现pipe-filter framew...
42 | 实现micro-kernel frame...
43 | 内置JSON解析
44 | easyjson
45 | HTTP服务
46 | 构建RESTful服务
47 | 性能分析工具
48 | 性能调优示例
49 | 别让性能被锁住
50 | GC友好的代码
51 | 高效字符串连接
52 | 面向错误的设计
53 | 面向恢复的设计
54 | Chaos Engineering
55 | 结束语
本节摘要
展开

精选留言(6)

  • 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
  • 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
  • 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
  • 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
  • 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了
    这是为什么?

    展开