encoding/base64和encoding/hex都支持几乎相同的函数集,但base64使用基于类的编码器,而hex在顶层导出方法.有没有一种简单的方法来创建一个围绕十六进制的包装器,以便您可以使用抽象的编码接口?更一般地说,有没有办法将方法绑定到结构?(例如,SomeStruct.Encode = hex.Encode)
到目前为止,我必须在hexEncoder结构上定义与函数具有相同签名的hex函数.我创建了一个这样的界面:
type Encoding interface {
Decode(dst, src []byte) (n int, err error)
DecodedLen(n int) int
Encode(dst, src []byte) // base64 returns nothing, hex returns int
EncodedLen(n int) int
}
Run Code Online (Sandbox Code Playgroud)
与之完美配合base64.StdEncoding,但我不知道如何包装十六进制方法.我为hex创建了一个空结构:
// wrap hex encoding/decoding so that it can be used interchangeably with base64 encoding
type hexEncoder struct {}
func (h hexEncoder) Decode(dst, src []byte) (n int, err error) {
return hex.Decode(dst, src)
}
func (h hexEncoder) DecodedLen(n int) int {
return hex.DecodedLen(n)
}
func (h hexEncoder) Encode(dst, src []byte) {
hex.Encode(dst, src) // don't return the int to match Encoding
}
func (h hexEncoder) EncodedLen(n int) int {
return hex.EncodedLen(n)
}
Run Code Online (Sandbox Code Playgroud)
这是有效的,但它是一堆额外的锅炉板(所有真正需要包装的是hex.Encode).有一个更好的方法吗?最终,目标是能够与编码/解码交替使用hex和base64,就像这样:
func convert(src []byte, decoder Encoding, encoder Encoding) ([]byte, error) {
temp := make([]byte, decoder.DecodedLen(len(src)))
n, err := decoder.Decode(temp, src)
if err != nil {
return temp, err
}
dst := make([]byte, encoder.EncodedLen(len(src)))
encoder.Encode(dst, temp[:n])
return dst, nil
}
Run Code Online (Sandbox Code Playgroud)
不,没有更好的方法来实现分派到另一个包中的函数的接口,说实话,我无法真正想象更好的方法会是什么样子。
你在那个包装中所说的是:
type myType struct{}
func (myType) WhenCalledLikeThis() { DoThat() }
Run Code Online (Sandbox Code Playgroud)
这似乎是最佳的。它不需要任何后备内存,允许对命名和返回值进行轻微更改(就像您对 所做的那样Encode),并通过单个调用进行分派。