go - YAML 解析解组失败
问题描述
我已经阅读了很多帖子,但经过多个小时的研究和尝试后仍然无法修复它,这是我的问题。
我有这个 YAML 文件:
---
filename: "Filename.txt"
steps:
-
mutationRaw:
name: "Random things..."
pattern: "12 34 56 78 9a bc de f0"
mask: "xxxxxxxx"
offset: 0
replace: "f0 de bc 9a 78 56 34 12"
-
mutationRaw:
name: "Some other random things..."
pattern: "00 00 12 34 56 78 9a bc de f0"
mask: "xxxxxxxxxx"
offset: 2
replace: "11 11 f0 de bc 9a 78 56 34 12"
这是我的 Go 代码:
package main
import (
"fmt"
"io/ioutil"
"gopkg.in/yaml.v3"
)
type patcherT struct {
Filename string `yaml:"filename"`
Steps struct {
MutationsRaw []struct {
Name string `yaml:"name"`
} `yaml:"mutationRaw,omitempty"`
} `yaml:"steps"`
}
func main() {
data, err := ioutil.ReadFile("struct.yaml")
if err != nil {
panic(err)
}
var patcher patcherT
err = yaml.Unmarshal(data, &patcher)
if err != nil {
panic(err)
}
fmt.Println("Patcher for ", patcher.Filename)
fmt.Println("Steps :")
for i := 0; i < len(patcher.Steps.MutationsRaw); i++ {
fmt.Println("\t- ", patcher.Steps.MutationsRaw[i].Name)
}
}
而这个错误:
第 4 行:不能将 !!seq 解组为 struct { MutationsRaw []struct { Name string "yaml:"name"" } "yaml:"mutationRaw,omitempty"" }
请注意,除了mutationRaw 之外,还可以使用mutationFile、deletionRaw、deletionFile 等。我可以这样做:
type patcherT struct {
Filename string `yaml:"filename"`
Steps []struct {
MutationsRaw struct {
Name string `yaml:"name"`
} `yaml:"mutationRaw,omitempty"`
} `yaml:"steps"`
}
但是,如果我保持相同的 YAML 结构,我会丢失太多信息。我真的很希望能够patcherT
通过patcher.Steps.MutationRaw[i]
, patcher.Steps.MutationFile[i]
, ... 解析我的结构,第一个结构使这种解析成为可能,但不起作用,而第二个结构使这种解析更难并且需要 YAML 更改,但可以。
简而言之,我如何解析这样的 YAML 结构以允许我不是在 Steps 上迭代,而是在 MutationsRaw(或 MutationsFile,...)上进行迭代?
解决方案
您可以在方法中使用自定义解组逻辑实现yaml.Unmarshaler接口。UnmarshalYAML
例如:
type patcherT struct {
Filename string `yaml:"filename"`
Steps Steps `yaml:"steps"`
}
type Steps struct {
MutationsRaw []struct {
Name string `yaml:"name"`
} `yaml:"mutationRaw,omitempty"`
}
func (s *Steps) UnmarshalYAML(unmarshal func(interface{}) error) error {
var tmpSteps []struct {
TmpMutationsRaw struct {
Name string `yaml:"name"`
} `yaml:"mutationRaw,omitempty"`
}
err := unmarshal(&tmpSteps)
if err != nil {
return err
}
*s = Steps{MutationsRaw: make([]struct {
Name string `yaml:"name"`
}, len(tmpSteps))}
for i, val := range tmpSteps {
s.MutationsRaw[i] = struct {
Name string `yaml:"name"`
}(struct{ Name string }{Name: val.TmpMutationsRaw.Name})
}
return nil
}
推荐阅读
- python - PySpark SQL 覆盖返回空表
- python - 在图例中将两个 matplotlib 标记合二为一
- javascript - React api 调用中的 Fetch 仍在等待中
- flutter - 如何禁用 minify 以进行 Flutter Web 发布构建
- sql-server - SQL Server 实例停止响应
- amazon-web-services - 如何将 aws 证书管理器连接到 terraform 中的 aws_alb_listener?
- express - 使用参数继续获得 404 路由
- ssl - 如何为通过 Kestrel 服务器托管 PWA 的 UWP 桌面桥应用配置 https
- c++ - leetcode 65. 有效数字如何理解状态转移表
- visual-studio-code - 设置拆分编辑器敏感度 - VS Code