无法在任意 Go 结构中使用反射更新嵌套字符串字段

我正在尝试使用 golang 中的反射为任意结构更新结构及其子字段中的所有字符串字段,如下所示:


package main

import (

    "fmt"

    "reflect"

    "strings"

)


func main() {

    type Inner struct {

        In1 string

        In2 []string

    }


    type Type struct {

        Name  string

        Names []string

        NewSt Inner

    }


    a := Type{

        Name:  " [ (Amir[ ",

        Names: nil,

        NewSt: Inner{

            In1: " [in1",

            In2: []string{"  [in2( "},

        },

    }


    trims(&a)

    fmt.Printf("%#v\n", a)

}


func trim(str string) string {

    return strings.TrimSpace(strings.Trim(str, "[](){}, "))

}


func trims(ps interface{}) {

    v := reflect.ValueOf(ps).Elem() // Elem() dereferences pointer

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

        fv := v.Field(i)

        switch fv.Kind() {

        case reflect.String:

            fv.SetString(trim(fv.String()))

        case reflect.Struct:

            in := fv.Interface()

            trims(&in)

        }

    }

}

但我感到恐慌:反射:在结构值错误上调用 reflect.Value.Elem。我该如何解决它,或者有什么更好的方法可以做到这一点?


皈依舞
浏览 118回答 1
1回答

波斯汪

func trims(ps interface{}) {&nbsp; &nbsp; v := reflect.ValueOf(ps)&nbsp; &nbsp; if v.Kind() == reflect.Ptr {&nbsp; &nbsp; &nbsp; &nbsp; v = v.Elem() // Elem() dereferences pointer&nbsp; &nbsp; }&nbsp; &nbsp; if v.Kind() != reflect.Struct {&nbsp; &nbsp; &nbsp; &nbsp; panic("not struct")&nbsp; &nbsp; }&nbsp; &nbsp; for i := 0; i < v.NumField(); i++ {&nbsp; &nbsp; &nbsp; &nbsp; fv := v.Field(i)&nbsp; &nbsp; &nbsp; &nbsp; switch fv.Kind() {&nbsp; &nbsp; &nbsp; &nbsp; case reflect.String:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fv.SetString(trim(fv.String()))&nbsp; &nbsp; &nbsp; &nbsp; case reflect.Struct:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // use Addr() to get an addressable&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // value of the field&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; in := fv.Addr().Interface()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // do not use &in, that evaluates&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // to *interface{}, that's almost&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // NEVER what you want&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; trims(in)&nbsp; &nbsp; &nbsp; &nbsp; case reflect.Slice:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if fv.Type().Elem().Kind() == reflect.String {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; for i := 0; i < fv.Len(); i++ {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fv.Index(i).SetString(trim(fv.Index(i).String()))&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }}https://go.dev/play/p/JkJTJzTckNA
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go