在JSON中使用Go的和类型(sum type)

huangapple go评论91阅读模式
英文:

Go sum type in json

问题

我想要实现的目标

我正在使用Go语言解析IAM策略。在IAM策略中,大多数字段可以是字符串或字符串数组。我很难在脑海中构建这些决策树,我想要的是一种详尽的模式匹配。

我所做的事情

我使用json.Unmarshal加载了一个策略。

type Policy struct {
	Version    string      `json:"Version"`
	Id         string      `json:"ID,omitempty"`
	Statements []Statement `json:"Statement"`
}

type Statement struct {
    // ...
	Action        interface{}         `json:"Action"`              // 字符串或数组
    // ...
}

然后遍历语句。

switch ele := st.Action.(type) {
case string:
	action, _ := expandAction(ele, data)
	actions = append(actions, action...)
	setter(i, actions)
case []string:
	for _, a := range ele {
		if strings.Contains(a, "*") {
			exps, _ := expandAction(a, data)
			actions = append(actions, exps...)
		} else {
			actions = append(actions, a)
		}
		setter(i, actions)
		fmt.Println(actions)
	}
default:
	// 接口类型
}

问题所在

它总是进入default情况。

可以使用反射,但我认为不应该使用反射,因为在调用json.Unmarshal时运行时可以知道类型。

英文:

What I want to achieve

I'm parsing IAM Policies in Go. In IAM Policies, most of the fields can be either a string or an array of strings. It's hard to think these decision trees in my head what I want is kind of exhaustive pattern matching.

What I did

I loeded a policy with json.Unmarshal

type Policy struct {
	Version    string      `json:"Version"`
	Id         string      `json:"ID,omitempty"`
	Statements []Statement `json:"Statement"`
}

type Statement struct {
    // ...
	Action        interface{}         `json:"Action"`              // string or array
    // ...
}

And iterating over statements.

switch ele := st.Action.(type) {
case string:
	action, _ := expandAction(ele, data)
	actions = append(actions, action...)
	setter(i, actions)
case []string:
	for _, a := range ele {
		if strings.Contains(a, "*") {
			exps, _ := expandAction(a, data)
			actions = append(actions, exps...)
		} else {
			actions = append(actions, a)
		}
		setter(i, actions)
		fmt.Println(actions)
	}
default:
	// interface{}
}

The Problem

It always goes to the default case.

Can use reflection, but don't think I really should, since runtime could know types when json.Unnarshal is called.

答案1

得分: 2

根据官方文档,JSON数组的类型是**[]interface**。如果你将[]string更新为[]interface,那么你就可以运行相关的case块。然而,如果你必须确保它是字符串数组,可以使用反射来实现。

英文:

As you can see from the official document the type for JSON array is []interface. If you update []string to []interface then you can run the related case block. However, if you have to sure that is array of string, reflection can provide it.

huangapple
  • 本文由 发表于 2022年7月31日 06:15:22
  • 转载请务必保留本文链接:https://go.coder-hub.com/73179394.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定