Go 语言从入门到实战
蔡超
Mobvista 技术副总裁兼首席架构师,前亚马逊(中国)首席软件架构师
48919 人已学习
新⼈⾸单¥59
课程目录
已完结/共 55 讲
第一章:Go语言简介 (4讲)
第二章:基本程序结构 (4讲)
第三章:常用集合 (3讲)
第四章:字符串 (1讲)
时长 16:47
第五章:函数 (2讲)
第六章:面向对象编程 (4讲)
第七章:编写好的错误处理 (2讲)
第八章:包和依赖管理 (2讲)
第九章:并发编程 (7讲)
第十章:典型并发任务 (5讲)
第十一章:测试 (3讲)
时长 11:48
时长 07:12
时长 06:15
第十二章:反射和Unsafe (3讲)
时长 08:18
时长 08:03
第十三章:常见架构模式的实现 (2讲)
第十四章:常见任务 (4讲)
时长 04:27
时长 05:14
第十五章:性能调优 (4讲)
第十六章:高可用性服务设计 (5讲)
Go 语言从入门到实战
登录|注册
留言
13
收藏
沉浸
阅读
分享
手机端
回顶部
当前播放: 39 | 万能程序
00:00 / 00:00
高清
  • 高清
1.0x
  • 2.0x
  • 1.5x
  • 1.25x
  • 1.0x
  • 0.75x
  • 0.5x
网页全屏
全屏
00:00
付费课程,可试看
01 | Go语言课程介绍
02 | 内容综述
03 | Go语言简介:历史背景、发展现状及语言特性
04 | 编写第一个Go程序
05 | 变量、常量以及与其他语言的差异
06 | 数据类型
07 | 运算符
08 | 条件和循环
09 | 数组和切片
10 | Map声明、元素访问及遍历
11 | Map与工厂模式,在Go语言中实现Set
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 framework
42 | 实现micro-kernel framework
43 | 内置JSON解析
44 | easyjson
45 | HTTP服务
46 | 构建RESTful服务
47 | 性能分析工具
48 | 性能调优示例
49 | 别让性能被锁住
50 | GC友好的代码
51 | 高效字符串连接
52 | 面向错误的设计
53 | 面向恢复的设计
54 | Chaos Engineering
55 | 结课测试&结束语
登录 后留言

全部留言(13)

  • 最新
  • 精选
芝士老爹
课程源码: 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.") }

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

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

2019-04-11
7
Geek_338030
好像有点懂老师的意思了,我这样理解是否正确呢? (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())

2019-09-22
2
1
Geek_338030
(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 }

2019-09-20
1
Geek_338030
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”

2019-09-20
1
草原fan
请教老师: vStr := reflect.ValueOf(st) vStr = vStr.Elem() 这个操作我看课程是放在for循环里的,这个是不是可以放在for循环之前,因为获取实例对象只需要一次就可以了,在for循环里只需执行vStr.FieldByName(k).Set(reflect.ValueOf(v))就行了

作者回复: 很好的发现!没错可以的。

2023-08-23
Redamancy
vstr.FieldByName(k).Set(reflect.ValueOf(v)) 我在执行这行语句报了panic panic: reflect: reflect.Value.Set using value obtained using unexported field 老师同学们能帮忙看下这个是为啥吗

作者回复: 你的Field的name是怎样的,首字母大写了吗

2022-02-06
escray
与配置有关的程序,很多都可以使用反射来写,其他语言或者框架也确实是这么做的。 在性能要求比较高的时候,要注意反射的性能。 反射代码的可读性也比较差,代码的 debug 难度也会增加。 看了一下留言里面 @Geek_338030 和老师关于 FieldByName 的讨论,不明觉厉,先留个印象,以后看到相关代码再回来。
2021-04-11
1
Nemo
`reflect.DeepEqual`是Go语言标准库`reflect`包中提供的一个函数,用于深度比较两个值是否相等。在使用`DeepEqual`进行比较时,如果两个值的类型相同,就会比较它们的值;如果类型不同,则直接返回false。`DeepEqual`支持比较多种类型的值,包括值类型、结构体、切片、映射、接口等。`DeepEqual`会递归比较每个值是否相等,直到找到不相等的值或者比较完所有的值为止。如果比较完所有的值都相等,则返回true,否则返回false。 需要注意的是,使用`DeepEqual`进行比较时,应该尽可能使用相同类型的值进行比较,否则可能会得到意想不到的结果。此外,`DeepEqual`比较值时,会比较所有的成员,包括私有成员。因此,在使用`DeepEqual`进行比较时,应该尽量使用公有成员,或者自定义`Equal`方法来进行比较。 在这段代码中,我们使用了`DeepEqual`函数进行了三组不同类型的值的比较,分别是: 1. 两个map,它们的键和值都是int和string类型,内容相同,所以比较结果为true; 2. 两个切片,它们的元素类型都是int,长度和内容都相同,所以比较结果为true; 3. 两个自定义的Customer结构体,它们的成员变量都相同,所以比较结果为true。 最后,我们在这段代码中也对比较操作符`==`进行了使用,用于比较两个Customer结构体的内容是否相等。这里需要注意,对于结构体类型,使用`==`进行比较时只有所有成员都相等时才相等。如果结构体中包含指针类型的成员变量,那么比较时需要保证指针指向的内容也相等。因此,使用`DeepEqual`函数进行比较更为保险和准确。
2023-04-18
Geek_a4cca6
老师,反射能动态给实例对象添加属性吗?
2022-05-29
收起评论