#go #struct #reflect
#Вперед #структура #отразить
Вопрос:
Я хотел бы знать, существует ли собственный способ преобразования строк, таких как:
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.
Ответ №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