Golang中如何将字符串转换为JSON键进行访问
Golang中如何将字符串转换为JSON键进行访问 我有一个映射(字符串),用于将“标签”转换为文本中的“词语” 这个“标签”列表必须被来自某个结构体的值所替换
示例:
var users struc {
login String `json:" options "`
passwd String `json:" options "`
}
var folders struc {
arch String `json:" folders "`
dest String `json:" folders "`
}
var TAGS = map [string] string {
"{login}": "users.login",
"{passwd}": "users.passwd",
"{archive}": "folders.arch",
"{dest}": "folders.dest",
}
类似这样:
var test = "Name = {login} archive = {archive} destination = {dest} / {login}"
var realTest = ReplaceTag (test, &TAGS)
我不知道如何将值中的字符串转换为结构体的实际值。 我知道如何直接操作,但当它以字符串形式存在时就不知道了。
我创建了一个“Go Playground”以便更清晰地说明:https://play.golang.org/p/qhmYnwiB5NO
提前感谢
更多关于Golang中如何将字符串转换为JSON键进行访问的实战教程也可以访问 https://www.itying.com/category-94-b0.html
所以你的问题是如何实现 ReplaceTag 来将
"Name = {login} archive = {archive} destination = {dest} / {login}"
转换为
"Name = users.login archive = folders.arch destination = folders.dest / users.login"
?
我理解得对吗?folders 和 users 是做什么用的?
更多关于Golang中如何将字符串转换为JSON键进行访问的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
这非常“像eval”。Go语言没有类似eval的函数。你可以使用这样的函数来实现类似功能:https://play.golang.org/p/mFsFrVAQjG_I,或者也可以使用模板:https://play.golang.org/p/bjHovjaoR7W
太棒了!非常感谢。
我稍微修改了一下,但原理是一样的,它可以工作。
var TAGS = map[string]string{
"{login}": "Users.Login",
"{passwd}": "Users.Passwd",
"{archive}": "Folders.Archive",
"{dest}": "Folders.Destination",
}
func main() {
conf := config{}
json.Unmarshal(jsonData, &conf)
var buf bytes.Buffer
for tag, value := range TAGS {
template.Must(template.New("").Parse("{{."+value+"}}")).Execute(&buf, conf)
TestString = strings.ReplaceAll(TestString, tag, string(buf.Bytes()))
buf.Reset()
}
fmt.Println(TestString)
}
不完全是这样。 我想用结构的 值 来替换。结构体本身反映了 JSON 文件的结果。
我创建了一个“Go Playground”来更清楚地说明:Go Playground - The Go Programming Language
注意: 如果我在 main() 中像这样使用“TAG”映射,这是可行的:
TAGS := map[string]string{
"{login}": conf.Users.Login,
"{passwd}": conf.Users.Passwd,
"{archive}": conf.Folders.Archive,
"{dest}": conf.Folders.Destination,
}
但是我需要在其他地方使用这个映射,所以我必须将其声明为全局变量。
在 PHP 中,我们可以这样做:
$Bar = "a";
$Foo = "Bar";
$World = "Foo";
$Hello = "World";
$a = "Hello";
$a; //返回 Hello
$$a; //返回 World
$$$a; //返回 Foo
$$$$a; //返回 Bar
$$$$$a; //返回 a
谢谢
在Go中,你可以使用反射(reflection)来根据字符串路径访问结构体的字段。以下是一个完整的解决方案:
package main
import (
"fmt"
"reflect"
"strings"
)
type Users struct {
Login string `json:"options"`
Passwd string `json:"options"`
}
type Folders struct {
Arch string `json:"folders"`
Dest string `json:"folders"`
}
var TAGS = map[string]string{
"{login}": "users.login",
"{passwd}": "users.passwd",
"{archive}": "folders.arch",
"{dest}": "folders.dest",
}
func getFieldValue(path string, data map[string]interface{}) string {
parts := strings.Split(path, ".")
if len(parts) != 2 {
return ""
}
objName := parts[0]
fieldName := parts[1]
if obj, ok := data[objName]; ok {
val := reflect.ValueOf(obj)
if val.Kind() == reflect.Ptr {
val = val.Elem()
}
field := val.FieldByName(strings.Title(fieldName))
if field.IsValid() && field.Kind() == reflect.String {
return field.String()
}
}
return ""
}
func ReplaceTag(text string, tags map[string]string, data map[string]interface{}) string {
result := text
for tag, path := range tags {
value := getFieldValue(path, data)
result = strings.ReplaceAll(result, tag, value)
}
return result
}
func main() {
users := &Users{
Login: "john_doe",
Passwd: "secret123",
}
folders := &Folders{
Arch: "/backup",
Dest: "/archive",
}
data := map[string]interface{}{
"users": users,
"folders": folders,
}
var test = "Name = {login} archive = {archive} destination = {dest} / {login}"
var realTest = ReplaceTag(test, TAGS, data)
fmt.Println(realTest)
// 输出: Name = john_doe archive = /backup destination = /archive / john_doe
}
如果你需要处理嵌套更深的结构体路径,可以使用这个更通用的版本:
func getFieldValueByPath(path string, data map[string]interface{}) string {
parts := strings.Split(path, ".")
if len(parts) < 2 {
return ""
}
objName := parts[0]
fieldPath := parts[1:]
if obj, ok := data[objName]; ok {
val := reflect.ValueOf(obj)
if val.Kind() == reflect.Ptr {
val = val.Elem()
}
for _, fieldName := range fieldPath {
if val.Kind() != reflect.Struct {
return ""
}
field := val.FieldByName(strings.Title(fieldName))
if !field.IsValid() {
return ""
}
val = field
}
if val.Kind() == reflect.String {
return val.String()
}
}
return ""
}
这个解决方案的关键点:
- 使用反射包(
reflect)来动态访问结构体字段 - 将结构体实例存储在map中以便按名称查找
- 通过
FieldByName方法根据字段名获取值 - 注意处理指针类型和字段名的首字母大写(Go的导出字段要求)
- 使用
strings.ReplaceAll进行标签替换

