亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何使用運行時定義的類型更新函數中接口的值?

如何使用運行時定義的類型更新函數中接口的值?

Go
波斯汪 2022-09-19 17:44:51
假設我有一個結構用戶type User struct {    Name     string `owm:"newNameFromAPI"`}下面的代碼初始化結構并將其傳遞給函數func main() {       dest := User{        Name: "Sebastien",    }        deepUpdate(dest, "owm")}該函數使用反射來迭代結構的所有字段并相應地更新它們(為清楚起見,刪除了幾個代碼塊)func deepUpdate(destinationInterface interface{}, selector string) {    // Here I'm not supposed to know that the type is `User`    // And if I just use dest := destinationInterface, the value won't update    dest := destinationInterface.(User)    // Pointer to struct - addressable    destVal := reflect.ValueOf(&dest)    destType := reflect.TypeOf(&dest)    // psindirect := reflect.Indirect(destVal) // ? ValueOf(<Ptr Value>) Requires to be adressed via reflect.Indirect() to access Field - https://stackoverflow.com/a/50098755/9077800    // Struct    destValElem := destVal.Elem()    destTypeElem := destType.Elem()    // Iterate over all fields of the struct    for i := 0; i < destValElem.NumField(); i++ {        // // for i := 0; i < destTypeElem.NumField(); i++ {        destValField := destValElem.Field(i)        destTypeField := destTypeElem.Field(i)        switch destValField.Kind() {        // Field is a struct        case reflect.Struct:            // Recursion            fmt.Println("IS A STRUCT")        default:            // Get the complete tag            tag := destTypeField.Tag            if len(tag) == 0 {                continue            }            // Get the value of our custom tag key            tagVal := tag.Get(selector)            if len(tagVal) == 0 {                continue            }           }問題是以下行,因為我不應該知道要將 轉換為 .destinationInterfaceUser如何將接口動態轉換為在運行時定義的某個未知類型,或者以任何其他方式獲取更新的“John”而不是“Sebastien”的相同輸出?Namedest := destinationInterface.(User)這是在戈朗游戲狗上運行的完整代碼https://play.golang.org/p/sYvz-Fwp97P
查看完整描述

1 回答

?
至尊寶的傳說

TA貢獻1789條經驗 獲得超10個贊

您不必知道 .該示例不是遞歸的,但可以輕松升級。dest


package main


import (

    "fmt"

    "reflect"

)


type User struct {

    Name string `owm:"newNameFromAPI"`

}


func main() {

    dest := User{

        Name: "Sebastien",

    }


    fmt.Println("Before:", dest.Name)

    deepUpdate(&dest, "owm")

    fmt.Println("After:", dest.Name)

}


func deepUpdate(dest interface{}, selector string) {

    //Get the reflect value of dest

    rv := reflect.ValueOf(dest)

    //Dereference every pointers

    for rv.Kind() == reflect.Ptr {

        rv = reflect.Indirect(rv)

    }


    //Check if its a struct, should use panic or return error

    if reflect.TypeOf(rv.Interface()).Kind() != reflect.Struct {

        fmt.Println("NOT A STRUCT")

        return

    }


    //Loop over the fields

    for i := 0; i < rv.NumField(); i++ {

        //Get the tag value

        tag := rv.Type().Field(i).Tag.Get(selector)

        if tag == "" {

            continue

        }


        //Get the source

        sourceValue := "John"


        //Assign the source to the dest's corresponding field

        if rv.Field(i).CanSet() {

            rv.Field(i).Set(reflect.ValueOf(sourceValue))

        }

    }

}

唯一的問題是,您必須使用與相應字段相同的類型。sourceValue


工作示例:https://goplay.space/#D0CmTaS5AiP


查看完整回答
反對 回復 2022-09-19
  • 1 回答
  • 0 關注
  • 93 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號