@
chaleaochexist 我之前的想法是: 当你要定义一个新 Job 的时候: Schedule(Callback,time) Callback 必然已经是一个静态的函数了,而要持久化,callback 又不能是闭包。那么比如要求 Callback 写成固定名 struct 的 method ,类似这样:
https://go.dev/play/p/cUw99-T55v8然后又想能不能根据类型信息反射出一个类实例,然后类实例包含一个重写掉的 Run method ,这样函数名就是固定的了,而且定义 Job 的方式能更灵活。 问题集中在怎么得到这个有类型的实例上——
然而研究了大概 6 个小时之后我发现
1. reflect.Type 也是一个接口,意味着就算把类型信息 dump 出来了,我也没法轻易构造出一个实例化的 Type
2. reflect.rtype 是 reflect.Type 接口最重要的实现,这个结构是有办法 dump 的( unsafe pointer 读),但不能存在覆写一个现存 reflect.rtype 的办法。 通过反射写这个结构会被 reflect.Value.SetXXX 的实现拒绝(有 flag 阻止写回去);而直接得到这个结构的 unsafepointer 尝试给它赋值会触发访问违例,原因不明。由于我也没用更 low level 的调试器去调( goland 而已),所以我也不知道是赋值语义还是类型转换语义的问题
3. 不像 C/++ 有函数地址就可以强制转换出一个函数; golang 是无论如何都先得有 reflect.Type 的(光有地址没有用)。由于 2 ,reflect.Type 不能自由构造,因此在语言范围内能想到的 tricky way 都堵死了。
有点蛋疼,前几天才有其他人说 golang 动态性差,确实是不得不承认的