如何重用第三方包中的结构,同时更改单个字段的编组行为?
短信预约 -IT技能 免费直播动态提醒
php小编子墨在这里分享一个关于如何重用第三方包中的结构并更改单个字段编组行为的技巧。当我们使用第三方包时,有时候我们需要对其中的某个字段进行自定义编组。本文将介绍一个简单的方法,可以通过继承和重写的方式来实现这一目标,既能重用原有的结构,又能满足个性化需求。接下来让我们一起来看看具体的实现方法吧!
问题内容
假设我想将一个结构编组到 YAML 中,并且该结构已经定义了其所有 YAML 标记,但有一个我想要更改的标记除外。如何在不更改结构本身的情况下更改此单个字段的行为?假设该结构来自第三方包。
这是一个要演示的示例,以及我的最佳尝试。假设 User
结构(及其关联的 Secret
结构)来自第三方包,因此我们无法修改它们。
package main
import (
"fmt"
"gopkg.in/yaml.v2"
)
type User struct {
Email string `yaml:"email"`
Password *Secret `yaml:"password"`
}
type Secret struct {
s string
}
// MarshalYAML implements the yaml.Marshaler interface for Secret.
func (sec *Secret) MarshalYAML() (interface{}, error) {
if sec != nil {
// Replace `""` with `sec.s`, and it gets the desired
// behavior. But I can't change the Secret struct:
return "", nil
}
return nil, nil
}
func (sec *Secret) UnmarshalYAML(unmarshal func(interface{}) error) error {
var st string
if err := unmarshal(&st); err != nil {
return err
}
sec.s = st
return nil
}
// My best attempt at the solution:
type SolutionAttempt struct {
User
}
func (sol *SolutionAttempt) MarshalYAML() (interface{}, error) {
res, err := yaml.Marshal(
struct {
// I don't like having to repeat all these fields from User:
Email string `yaml:"email"`
Password string `yaml:"password"`
}{
Email: sol.User.Email,
Password: sol.User.Password.s,
},
)
if err != nil {
return nil, err
}
return string(res), nil
}
func main() {
user := &User{}
var data = `
email: [email protected]
password: asdf
`
err := yaml.Unmarshal([]byte(data), user)
if err != nil {
fmt.Printf("errors! %s", err)
return
}
buf, err := yaml.Marshal(user)
if err != nil {
fmt.Printf("errors! %s", err)
return
}
// Without touching User or Secret, how can I unmarshall an
// instance of User that renders the secret?
fmt.Printf("marshalled output:\n%s\n", buf)
///////////////////////////////////////////////////////
// attempted solution:
///////////////////////////////////////////////////////
sol := &SolutionAttempt{}
var data2 = `
user:
email: [email protected]
password: asdf
`
err = yaml.Unmarshal([]byte(data2), sol)
if err != nil {
fmt.Printf("errors! %s", err)
return
}
buf, err = yaml.Marshal(sol)
if err != nil {
fmt.Printf("errors! %s", err)
return
}
fmt.Printf("attempted solution marshalled output:\n%s\n", buf)
}
这是上述代码的 Go Playground 链接:https://go.dev/play/p/ojiPv4ylCEq
解决方法
这根本不可能。
你的“最佳尝试”就是正确的道路。
以上就是如何重用第三方包中的结构,同时更改单个字段的编组行为?的详细内容,更多请关注编程网其它相关文章!
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341