欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

golang 實(shí)現(xiàn)兩個(gè)結(jié)構(gòu)體復(fù)制字段

 更新時(shí)間:2021年04月28日 14:27:44   作者:butterfly5211314  
這篇文章主要介紹了golang 實(shí)現(xiàn)兩個(gè)結(jié)構(gòu)體復(fù)制字段,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧

實(shí)際工作中可能會(huì)有這樣的場(chǎng)景:

兩個(gè)結(jié)構(gòu)體(可能類型一樣), 字段名和類型都一樣, 想復(fù)制一個(gè)結(jié)構(gòu)體的全部或者其中某幾個(gè)字段的值到另一個(gè)(即merge操作),

自然想到可以用反射實(shí)現(xiàn)

package main
import "fmt"
import "reflect"
// 用b的所有字段覆蓋a的
// 如果fields不為空, 表示用b的特定字段覆蓋a的
// a應(yīng)該為結(jié)構(gòu)體指針
func CopyFields(a interface{}, b interface{}, fields ...string) (err error) {
	at := reflect.TypeOf(a)
	av := reflect.ValueOf(a)
	bt := reflect.TypeOf(b)
	bv := reflect.ValueOf(b)
	// 簡(jiǎn)單判斷下
	if at.Kind() != reflect.Ptr {
		err = fmt.Errorf("a must be a struct pointer")
		return
	}
	av = reflect.ValueOf(av.Interface())
	// 要復(fù)制哪些字段
	_fields := make([]string, 0)
	if len(fields) > 0 {
		_fields = fields
	} else {
		for i := 0; i < bv.NumField(); i++ {
			_fields = append(_fields, bt.Field(i).Name)
		}
	}
	if len(_fields) == 0 {
		fmt.Println("no fields to copy")
		return
	}
	// 復(fù)制
	for i := 0; i < len(_fields); i++ {
		name := _fields[i]
		f := av.Elem().FieldByName(name)
		bValue := bv.FieldByName(name)
		// a中有同名的字段并且類型一致才復(fù)制
		if f.IsValid() && f.Kind() == bValue.Kind() {
			f.Set(bValue)
		} else {
			fmt.Printf("no such field or different kind, fieldName: %s\n", name)
		}
	}
	return
}
type S1 struct {
    Name string
    Age int
}
type S2 struct {
    Name string
    Age int32
}
func main() {
    s1 := S1{"hello", 22}
    s2 := S2{"world", 33}
    fmt.Println(s1, s2)
    CopyFields(&s1, s2)
    fmt.Println(s1, s2)
}

上述例子輸出為:

{hello 22} {world 33}

no such field or different kind, fieldName: Age

{world 22} {world 33}

可見(jiàn)s2的Name字段值已經(jīng)成功被覆蓋.

而s2中Age字段和s1中Age字段類型不一樣, 會(huì)忽略.

其實(shí)上面的還可以優(yōu)化, 畢竟int32和int還是可以認(rèn)為是"一樣"的類型的,

不過(guò)思路就是這樣.

補(bǔ)充:golang使用反射將一個(gè)結(jié)構(gòu)體的數(shù)據(jù)直接復(fù)制到另一個(gè)結(jié)構(gòu)體中(通過(guò)相同字段)

看代碼吧~

package main
import (
	"fmt"
	"reflect"
)
type A struct {
	Name   string
	Gender string
	Age    int
}
type B struct {
	Name   string
	Gender string
}
//binding type interface 要修改的結(jié)構(gòu)體
//value type interace 有數(shù)據(jù)的結(jié)構(gòu)體
func structAssign(binding interface{}, value interface{}) {
	bVal := reflect.ValueOf(binding).Elem() //獲取reflect.Type類型
	vVal := reflect.ValueOf(value).Elem()   //獲取reflect.Type類型
	vTypeOfT := vVal.Type()
	for i := 0; i < vVal.NumField(); i++ {
		// 在要修改的結(jié)構(gòu)體中查詢有數(shù)據(jù)結(jié)構(gòu)體中相同屬性的字段,有則修改其值
		name := vTypeOfT.Field(i).Name
		if ok := bVal.FieldByName(name).IsValid(); ok {
			bVal.FieldByName(name).Set(reflect.ValueOf(vVal.Field(i).Interface()))
		}
	}
}
func main() {
	as := A{}
	bs := B{Name: "wfy", Gender: "男"}
	fmt.Println(as)
	structAssign(&as, &bs)
	fmt.Println(as)
}

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教。

相關(guān)文章

  • 詳解Go語(yǔ)言如何實(shí)現(xiàn)類似Python中的with上下文管理器

    詳解Go語(yǔ)言如何實(shí)現(xiàn)類似Python中的with上下文管理器

    熟悉?Python?的同學(xué)應(yīng)該知道?Python?中的上下文管理器非常好用,那么在?Go?中是否也能實(shí)現(xiàn)上下文管理器呢,下面小編就來(lái)和大家仔細(xì)講講吧
    2023-07-07
  • golang sudog指的是什么

    golang sudog指的是什么

    sudog代表在等待隊(duì)列中的goroutine,比如channel發(fā)送接受,由于goroutine和同步對(duì)象的關(guān)系是多對(duì)多,因此需要sudog映射,本文重點(diǎn)介紹golang sudog指的是什么,感興趣的朋友一起看看吧
    2024-02-02
  • golan參數(shù)校驗(yàn)Validator

    golan參數(shù)校驗(yàn)Validator

    這篇文章主要介紹了golan參數(shù)校驗(yàn)Validator,validator包可以通過(guò)反射結(jié)構(gòu)體struct的tag進(jìn)行參數(shù)校驗(yàn),下面來(lái)看看文章的詳細(xì)介紹吧,需要的朋友也可以參考一下
    2021-12-12
  • Go語(yǔ)言正則表達(dá)式用法實(shí)例小結(jié)【查找、匹配、替換等】

    Go語(yǔ)言正則表達(dá)式用法實(shí)例小結(jié)【查找、匹配、替換等】

    這篇文章主要介紹了Go語(yǔ)言正則表達(dá)式用法,結(jié)合實(shí)例形式分析了Go語(yǔ)言基于正則實(shí)現(xiàn)查找、匹配、替換等基本操作的實(shí)現(xiàn)技巧,需要的朋友可以參考下
    2017-01-01
  • golang中"var"與":="的區(qū)別解析

    golang中"var"與":="的區(qū)別解析

    這篇文章主要介紹了golang中“var”與“:=”的區(qū)別,使用var關(guān)鍵字是Go最基本的定義變量方式,有時(shí)也會(huì)使用到:=來(lái)定義變量,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-04-04
  • Golang微服務(wù)框架Kratos實(shí)現(xiàn)Kafka消息隊(duì)列的方法

    Golang微服務(wù)框架Kratos實(shí)現(xiàn)Kafka消息隊(duì)列的方法

    消息隊(duì)列是大型分布式系統(tǒng)不可缺少的中間件,也是高并發(fā)系統(tǒng)的基石中間件,所以掌握好消息隊(duì)列MQ就變得極其重要,在本文當(dāng)中,您將了解到:什么是消息隊(duì)列?什么是Kafka?怎樣在微服務(wù)框架Kratos當(dāng)中應(yīng)用Kafka進(jìn)行業(yè)務(wù)開(kāi)發(fā),需要的朋友可以參考下
    2023-09-09
  • VSCode配置Go插件和第三方拓展包的詳細(xì)教程

    VSCode配置Go插件和第三方拓展包的詳細(xì)教程

    這篇文章主要介紹了VSCode配置Go插件和第三方拓展包的詳細(xì)教程,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-05-05
  • golang實(shí)現(xiàn)大文件上傳功能全過(guò)程

    golang實(shí)現(xiàn)大文件上傳功能全過(guò)程

    Go語(yǔ)言可以用來(lái)實(shí)現(xiàn)大文件傳輸,下面這篇文章主要給大家介紹了關(guān)于golang實(shí)現(xiàn)大文件上傳功能的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-07-07
  • golang-gin-mgo高并發(fā)服務(wù)器搭建教程

    golang-gin-mgo高并發(fā)服務(wù)器搭建教程

    這篇文章主要介紹了golang-gin-mgo高并發(fā)服務(wù)器搭建教程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-12-12
  • 淺析Go中序列化與反序列化的基本使用

    淺析Go中序列化與反序列化的基本使用

    序列化是指將對(duì)象轉(zhuǎn)換成字節(jié)流,從而存儲(chǔ)對(duì)象或?qū)?duì)象傳輸?shù)絻?nèi)存、數(shù)據(jù)庫(kù)或文件的過(guò)程,反向過(guò)程稱為“反序列化”。本文主要介紹了Go中序列化與反序列化的基本使用,需要的可以參考一下
    2023-04-04

最新評(píng)論