6

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
}

与 完美配合base64.StdEncoding,但我不清楚如何包装十六进制方法。我为十六进制创建了一个空结构:

// 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)
}

这行得通,但它是一堆额外的样板(真正需要包装的是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
}
4

1 回答 1

2

不,没有更好的方法来实现一个接口,该接口调度到另一个包中的函数,老实说,我真的无法想象更好的方法会是什么样子。

你在那个包装里说的是:

type myType struct{}

func (myType) WhenCalledLikeThis() { DoThat() }

这似乎是最佳的。它不需要任何后备内存,允许对命名和返回值进行细微更改(就像您对 所做的那样Encode),并且只需一次调用即可调度。

于 2013-09-09T15:24:18.550 回答