Closed flycash closed 2 years ago
仅限中文
早期我在设计 eorm 处理结果集的部分的时候,最开始的想法是引入一个中间表达:
即我们最开始读取返回的查询结果集,我们使用 []byte 来接收,这个是一个中间表达。通过这样一个中间表达,我们可以在将结果集拼装成对象之前,做一些事情。
但是后来我发现这里面有两个缺点:
所以最终我又去掉了这个中间表达,但是代码里面还有一些遗留代码。
这一次我们将去掉 valuer/unsafe 里面的相关代码:
valuer/unsafe
func (u unsafeValue) Field(name string) (interface{}, error) { fd, ok := u.meta.FieldMap[name] if !ok { return nil, errs.NewInvalidFieldError(name) } ptr := unsafe.Pointer(uintptr(u.addr) + fd.Offset) if fd.IsHolderType { val := reflect.NewAt(fd.Typ, ptr).Elem() return val.Interface(), nil } switch fd.Typ.Kind() { case reflect.Bool: return *(*bool)(ptr), nil case reflect.Int: return *(*int)(ptr), nil case reflect.Int8: return *(*int8)(ptr), nil case reflect.Int16: return *(*int16)(ptr), nil case reflect.Int32: return *(*int32)(ptr), nil case reflect.Int64: return *(*int64)(ptr), nil case reflect.Uint: return *(*uint)(ptr), nil case reflect.Uint8: return *(*uint8)(ptr), nil case reflect.Uint16: return *(*uint16)(ptr), nil case reflect.Uint32: return *(*uint32)(ptr), nil case reflect.Uint64: return *(*uint64)(ptr), nil case reflect.Float32: return *(*float32)(ptr), nil case reflect.Float64: return *(*float64)(ptr), nil case reflect.String: return *(*string)(ptr), nil case reflect.Slice: // Array 只有一种可能,那就是 []byte return *(*[]byte)(ptr), nil case reflect.Pointer: ele := fd.Typ.Elem() switch ele.Kind() { case reflect.Bool: return *(**bool)(ptr), nil case reflect.Int: return *(**int)(ptr), nil case reflect.Int8: return *(**int8)(ptr), nil case reflect.Int16: return *(**int16)(ptr), nil case reflect.Int32: return *(**int32)(ptr), nil case reflect.Int64: return *(**int64)(ptr), nil case reflect.Uint: return *(**uint)(ptr), nil case reflect.Uint8: return *(**uint8)(ptr), nil case reflect.Uint16: return *(**uint16)(ptr), nil case reflect.Uint32: return *(**uint32)(ptr), nil case reflect.Uint64: return *(**uint64)(ptr), nil case reflect.Float32: return *(**float32)(ptr), nil case reflect.Float64: return *(**float64)(ptr), nil default: return nil, errs.NewUnsupportedTypeError(fd.Typ) } default: return nil, errs.NewUnsupportedTypeError(fd.Typ) } }
这一大堆的 switch case,就是在引入中间结果 []byte 之后遗留产物,包括对 IsHolderType 的处理也是。
IsHolderType
这个时候我们可以直接删除掉大部分代码:
func (u unsafeValue) Field(name string) (interface{}, error) { fd, ok := u.meta.FieldMap[name] if !ok { return nil, errs.NewInvalidFieldError(name) } ptr := unsafe.Pointer(uintptr(u.addr) + fd.Offset) val := reflect.NewAt(fd.Typ, ptr).Elem() return val.Interface(), nil }
任何你觉得有利于解决问题的补充说明
上传 go env 的结果
go env
仅限中文
使用场景
早期我在设计 eorm 处理结果集的部分的时候,最开始的想法是引入一个中间表达:
即我们最开始读取返回的查询结果集,我们使用 []byte 来接收,这个是一个中间表达。通过这样一个中间表达,我们可以在将结果集拼装成对象之前,做一些事情。
但是后来我发现这里面有两个缺点:
所以最终我又去掉了这个中间表达,但是代码里面还有一些遗留代码。
这一次我们将去掉
valuer/unsafe
里面的相关代码:这一大堆的 switch case,就是在引入中间结果 []byte 之后遗留产物,包括对
IsHolderType
的处理也是。这个时候我们可以直接删除掉大部分代码:
其它
你使用的是 eorm 哪个版本?
你设置的的 Go 环境?