Как преобразовать любую строку в имя поля структуры, как - PullRequest
0 голосов
/ 01 апреля 2019

Я хотел бы знать, существует ли собственный способ преобразования строк, например:

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

В строке, следующей за соглашением для открытых структур членов структуры, в Go.

Идея состоит в том, чтобы написать функцию, которая принимаетstring и попытайтесь получить значение поля, даже если переданная строка не использует соглашение 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.

Ответы [ 2 ]

3 голосов
/ 01 апреля 2019

Волшебством регулярных выражений

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
1 голос
/ 01 апреля 2019
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

...