go基于泛型实现继承

概述

在某些情况下,我们需要继承的时候父类的函数和方法能够影响(或使用)子类的一些数据,这并不符合一般情况下的类原则,但是很有用。
在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
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值