当前位置:网站首页>go基于泛型实现继承
go基于泛型实现继承
2022-08-08 20:53:00 【Chise1】
概述
在某些情况下,我们需要继承的时候父类的函数和方法能够影响(或使用)子类的一些数据,这并不符合一般情况下的类原则,但是很有用。
在go里面,我们通过组合实现继承,但是组合的类没办法操作同级别的类,解决方案是把操作方法提出来作为函数进行处理。
对于有些情况下,明明是紧密耦合的函数,却不得不拆出来单独使用,还是让人很不爽。
好在go的泛型能够解决这个问题。
下面是我基于go泛型实现的一个动态结构体,包含一些固定的基本字段以及一些动态字段。在某些需要直接从请求参数获取字段名并赋值的需求的时候,这个操作很有用。特别是一个结构体几十个字段的时候:
package models
import (
"encoding/json"
"reflect"
"regexp"
)
type Info[T any] struct {
T T //固定字段,对于一般情况下会本身会读取到的字段写入这里
Ext map[string]interface{
} // 其它扩展数据,根据需要添加,key/value形式获取
}
func NewInfo[T any]() Info[T] {
// 主要是为了初始化map
res := Info[T]{
}
res.Ext = map[string]interface{
}{
}
return res
}
func (s Info[T]) MarshalJSON() ([]byte, error) {
// 将动态字段和静态字段组合放到一个结构体
marshal, err := json.Marshal(s.T)
if err != nil {
return nil, err
}
if len(s.Ext) != 0 {
extMarshal, err := json.Marshal(s.Ext)
if err != nil {
return nil, err
}
marshal = append(marshal[0:len(marshal)-1], []byte(`,"__ext__":{},`)...)
marshal = append(marshal, extMarshal[1:]...)
}
return marshal, nil
}
func (s *Info[T]) UnmarshalJSON(data []byte) error {
// 反序列化
dataS := string(data)
subInfo := regexp.MustCompile(`,"__ext__":{},`).Split(dataS, 2)
if len(subInfo) == 1 {
//未找到对象
return json.Unmarshal(data, &s.T)
} else {
baseStr := subInfo[0] + "}"
extStr := "{" + subInfo[1]
err := json.Unmarshal([]byte(baseStr), &s.T)
if err != nil {
return err
}
ext := map[string]interface{
}{
}
err = json.Unmarshal([]byte(extStr), &ext)
if err != nil {
return err
}
s.Ext = ext
return nil
}
}
func (s Info[T]) GetAttr(fieldName string) (v interface{
}, find bool) {
// 根据字符串获取值,这里甚至可以改造为忽略大小写
refval := reflect.ValueOf(s)
val := refval.FieldByName(fieldName)
if val.IsValid() {
return val.Interface(), true
}
dynamicStruct, ok := s.Ext[fieldName]
return dynamicStruct, ok
}
func (s *Info[T]) SetAttr(fieldName string, value interface{
}) bool {
//根据字符串写入值,这里也可以忽略大小写
refval := reflect.ValueOf(s).Elem()
val := refval.FieldByName(fieldName)
if val.IsValid() {
val.Set(reflect.ValueOf(value))
return true
}
s.Ext[fieldName] = value
return false
}
边栏推荐
猜你喜欢
随机推荐
Process实现守护线程
Redis Bloom Filter
The new library online | CnOpenDataA shares of the listed company basic information data
360杜跃进ISC演讲:保障信创软件的可信性和安全性是信创安全体系的基础
Kotlin注解
PHPUnit 单元测试
Kotlin之JSON格式解析
头脑风暴:打家劫舍2
Some useful frameworks in Kotlin
Swoole 健康检查
MySQL权限管理
Kotlin-学习的第五天之Handler
Kotlin笔记-ForEach与ForEachIndexed区别
Flask 教程 第十章:邮件支持
关于KotlinAndroid遇到的小知识
跨域问题 什么时候出现跨域问题 如何解决跨域问题
Mysql管理指令
Kotlin - learn the fifth day of the Handler
莫让“学院派”限制我们的思维:在数组的中间位置删除数据一定比链表慢?
莅临GOPS大会龙智展位,获取Forrester最新报告:《Forrester Wave:2021年第四季度企业服务管理报告》