如何在Go中将字节数组渲染为YAML格式的字符串?

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

How to render a byte array as a string in YAML in Go?

问题

我有一个包含字节数组字段的结构体。以下是代码:

package main

import (
	"fmt"

	"gopkg.in/yaml.v3"
)

type A struct {
	PublicKey []byte `json:"PublicKey" yaml:"PublicKey"`
}

// 实现 yaml 包的 Marshaler 接口
func (a A) MarshalYAML() (interface{}, error) {
	type alias A

	node := yaml.Node{}
	_ = node.Encode(alias(a))

	return node, nil
}

func PublicKey() {
	token := []byte{87, 88, 89, 90}

	a := A{PublicKey: token}

	fmt.Printf("A: %+v\nA.PublicKey:%s\n\n", a, a.PublicKey)
	out, _ := yaml.Marshal(a)
	fmt.Println(string(out))
}

func main() {
	PublicKey()
}

以下是输出结果:

A: {PublicKey:[87 88 89 90]}
A.PublicKey:WXYZ

PublicKey:
    - 87
    - 88
    - 89
    - 90

是否可能将其输出为字符串而不是字节数组?例如:

PublicKey: WXYZ
英文:

I have a struct with a byte array as a field. Here's the code:

package main

import (
	"fmt"

	"gopkg.in/yaml.v3"
)

type A struct {
	PublicKey []byte `json:"PublicKey" yaml:"PublicKey"`
}

// Implements the Marshaler interface of the yaml pkg.
func (a A) MarshalYAML() (interface{}, error) {
	type alias A

	node := yaml.Node{}
	_ = node.Encode(alias(a))

	return node, nil
}

func PublicKey() {
	token := []byte{87, 88, 89, 90}

	a := A{PublicKey: token}

	fmt.Printf("A: %+v\nA.PublicKey:%s\n\n", a, a.PublicKey)
	out, _ := yaml.Marshal(a)
	fmt.Println(string(out))
}

func main() {
	PublicKey()
}

Here's the output:

A: {PublicKey:[87 88 89 90]}
A.PublicKey:WXYZ

PublicKey:
    - 87
    - 88
    - 89
    - 90

Is it possible to have the marshal-er output it as a string instead of a byte array? E.g.:

PublicKey: WXYZ

答案1

得分: 2

// 对于 `A`,我更倾向于为公钥创建自定义类型,并使用Base64对其值进行编码/解码,而不是自定义编解码器

type PubKey []byte

func (pk PubKey) MarshalYAML() (interface{}, error) {
	return base64.StdEncoding.EncodeToString(pk), nil
}

func (pk *PubKey) UnmarshalYAML(node *yaml.Node) error {
	value := node.Value
	ba, err := base64.StdEncoding.DecodeString(value)
	if err != nil {
		return err
	}
	*pk = ba
	return nil
}

type A struct {
	PublicKey PubKey `json:"PublicKey" yaml:"PublicKey"`
}

// 没有自定义的YAML编解码器

// 编码/解码示例:
func PublicKey() {
	token := []byte{87, 88, 89, 90}

	a := A{PublicKey: token}

	fmt.Printf("A: %+v\nA.PublicKey:%s\n\n", a, a.PublicKey)
	out, _ := yaml.Marshal(a)
	fmt.Println("Encoded: ", string(out))

	var b A
	err := yaml.Unmarshal(out, &b)
	if err != nil {
		println(err)
	}
	fmt.Printf("解码后: %+v\n", b)
}

完整示例https://go.dev/play/p/2_gMi9sazIp

结果为
A: {PublicKey:[87 88 89 90]}
A.PublicKey:WXYZ

Encoded:  PublicKey: V1hZWg==

解码后: {PublicKey:[87 88 89 90]}

顺便提一下Base64是[JSON编解码器如何对字节切片进行编码][1]
使用你的数据的示例https://go.dev/play/p/dGr0i0DnnNX

结果为
A: {PublicKey:[87 88 89 90]}
A.PublicKey:WXYZ

Encoded JSON:  {"PublicKey":"V1hZWg=="}
解码后 JSON: {PublicKey:[87 88 89 90]}
英文:

Instead of customizing codec for A I'd rather make custom type for the public key and use Base64 to encode/decode its value

type PubKey []byte
func (pk PubKey) MarshalYAML() (interface{}, error) {
return base64.StdEncoding.EncodeToString(pk), nil
}
func (pk *PubKey) UnmarshalYAML(node *yaml.Node) error {
value := node.Value
ba, err := base64.StdEncoding.DecodeString(value)
if err != nil {
return err
}
*pk = ba
return nil
}
type A struct {
PublicKey PubKey `json:"PublicKey" yaml:"PublicKey"`
}
// No custom YAML codec

Coding/decoding goes like this:

func PublicKey() {
token := []byte{87, 88, 89, 90}
a := A{PublicKey: token}
fmt.Printf("A: %+v\nA.PublicKey:%s\n\n", a, a.PublicKey)
out, _ := yaml.Marshal(a)
fmt.Println("Encoded: ", string(out))
var b A
err := yaml.Unmarshal(out, &b)
if err != nil {
println(err)
}
fmt.Printf("after decoding: %+v\n", b)
}

Full example https://go.dev/play/p/2_gMi9sazIp

The result is:

A: {PublicKey:[87 88 89 90]}
A.PublicKey:WXYZ
Encoded:  PublicKey: V1hZWg==
after decoding: {PublicKey:[87 88 89 90]}

BTW, base64 is how json codec marshals byte slices
Example with your data: https://go.dev/play/p/dGr0i0DnnNX

A: {PublicKey:[87 88 89 90]}
A.PublicKey:WXYZ
Encoded JSON:  {"PublicKey":"V1hZWg=="}
after decoding JSON: {PublicKey:[87 88 89 90]}

huangapple
  • 本文由 发表于 2022年9月28日 11:17:14
  • 转载请务必保留本文链接:https://go.coder-hub.com/73875847.html
匿名

发表评论

匿名网友

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

确定