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

Nested string fields can not be updated using reflection in an arbitrary Go struct

我正在尝试使用 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 on struct Value 错误。 我该如何修复它,或者有什么更好的方法可以做到这一点??

谢谢。

func trims(ps interface{}) {
    v := reflect.ValueOf(ps)
    if v.Kind() == reflect.Ptr {
        v = v.Elem() // Elem() dereferences pointer
    }
    if v.Kind() != reflect.Struct {
        panic("not struct")
    }
    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:
            // use Addr() to get an addressable
            // value of the field
            in := fv.Addr().Interface()

            // do not use &in, that evaluates
            // to *interface{}, that's almost
            // NEVER what you want
            trims(in)
        case reflect.Slice:
            if fv.Type().Elem().Kind() == reflect.String {
                for i := 0; i < fv.Len(); i++ {
                    fv.Index(i).SetString(trim(fv.Index(i).String()))
                }
            }
        }
    }
}

https://go.dev/play/p/JkJTJzTckNA