【问题标题】:How to transform any string in struct field name like如何转换结构字段名称中的任何字符串,例如
【发布时间】:2019-04-01 00:39:28
【问题描述】:

我想知道是否有一种本地方式来转换字符串,例如:

  • a.string
  • a-string
  • a_string
  • a string

在遵循结构公共字段成员约定的字符串中,在 Go 中。

想法是写一个接受字符串的函数,并尝试获取字段的值,即使传递的字符串没有使用PascalCase约定,例如:

type MyStruct struct {
    Debug   bool
    AString bool
    SomethingMoreComplex
}

var myStruct MyStruct

func GetField(s string) reflect.Value {
   v := reflect.ValueOf(myStruct)
   return v.FieldByName(s)
}

function main() {
    GetField("debug")
    GetField("a.string")
    GetField("a-string")
    GetField("a_string")
    GetField("-a.string")
    GetField("something-more-complex")
}

我使用的是 strcase 包,但它只适用于 ASCII。

【问题讨论】:

    标签: go struct reflect


    【解决方案1】:

    正则表达式的魔力

    https://goplay.space/#xHfxG249CsH

    package main
    
    import (
        "fmt"
        "regexp"
        "strings"
    )
    
    func ConvertFieldName(s string) string {
        r := regexp.MustCompile("(\\b|-|_|\\.)[a-z]")
        return r.ReplaceAllStringFunc(s, func(t string) string {
            if len(t) == 1 {
                return strings.ToUpper(t)
            } else {
                return strings.ToUpper(string(t[1]))
            }
    
        })
    
    }
    
    func main() {
        fmt.Println(ConvertFieldName("debug"))
        fmt.Println(ConvertFieldName("a.string"))
        fmt.Println(ConvertFieldName("a-string"))
        fmt.Println(ConvertFieldName("a_string"))
        fmt.Println(ConvertFieldName("-a.string"))
        fmt.Println(ConvertFieldName("something-more-complex"))
    }
    

    输出

    Debug
    AString
    AString
    AString
    AString
    SomethingMoreComplex
    

    【讨论】:

      【解决方案2】:
      package main
      
      import (
          "fmt"
          "reflect"
      )
      
      type MyStruct struct {
          Debug   bool
          AString bool
      }
      
      var myStruct MyStruct
      
      func GetField(s string) (reflect.Value, error) {
          t := reflect.TypeOf(myStruct)
          v := reflect.ValueOf(myStruct)
          for fieldIndex := 0; fieldIndex < v.NumField(); fieldIndex++ {
              if t.Field(fieldIndex).Name == s {
                  return v.Field(fieldIndex), nil
              }
      
          }
          return reflect.Value{}, fmt.Errorf("%s not exist", s)
      }
      
      func main() {
          var v reflect.Value
          var err error
      
          v, err = GetField("Debug")
          fmt.Println(v, err)
      
          v, err = GetField("debug")
          fmt.Println(v, err)
      }
      

      另外,你可以尝试定义自己的字段标签,比如json tag

      【讨论】:

        猜你喜欢
        • 2022-01-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-02-06
        • 2023-03-15
        • 2021-06-28
        • 1970-01-01
        相关资源
        最近更新 更多