2013-09-03 17 views
6

codifica/base64 e codifica/hex supportano quasi lo stesso insieme di funzioni, ma base64 utilizza un codificatore basato su classe, mentre hex esporta i metodi al livello superiore. C'è un modo semplice per creare un wrapper attorno a hex in modo da poter lavorare con un'interfaccia di codifica astratta? Più in generale, c'è un modo per fare l'equivalente di unire un metodo a una struct? (ad esempio, SomeStruct.Encode = hex.Encode)L'aggiunta di funzioni "statiche" a una struct

Finora, ho dovuto definire le funzioni su una struttura hexEncoder con la stessa firma delle funzioni hex. Ho creato un'interfaccia simile a questo:

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 
} 

che funziona perfettamente con base64.StdEncoding, ma io non sono stato chiaro su come avvolgere i metodi esagonali. Ho creato un vuoto per struct 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) 
} 

Questo funziona, ma è un gruppo di piastra caldaia supplementare (dove tutto ciò che necessita di essere avvolto è hex.Encode). C'è un modo migliore per farlo? Infine, l'obiettivo è quello di essere in grado di utilizzare esadecimale e base64 in modo intercambiabile con la codifica/decodifica, come in qualcosa di simile:

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 
} 
+0

Sembra più una richiesta di funzionalità che una domanda SO. Probabilmente è solo una svista. Sfortunatamente è attivo il congelamento delle funzionalità 1.2, quindi la prima aggiunta potrebbe essere la 1.3. –

+1

@KyleLemons altri pacchetti di codifica sono impostati in modo diverso ... non è chiaro se c'è davvero una configurazione standard (a parte un metodo Encoder che accetta byte sorgente e destinazione) –

+1

Mentre l'interfaccia che stai usando potrebbe non funzionare per tutte le codifiche, potrebbe esserci un modo per poter essere standardizzati. Base64 e Hex sembrano certamente avere un modo standard per funzionare. Immagina, per esempio, un metodo/funzione AppendTo-like che non richieda la conoscenza del Len. –

risposta

2

No, non c'è modo migliore per implementare un'interfaccia che invia alle funzioni in un altro pacchetto e, onestamente, non riesco davvero a immaginare come sarebbe il modo migliore.

Quello che stai dicendo in quel involucro è:

type myType struct{} 

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

Il che sembra ottimale. Non ha bisogno di alcuna memoria di supporto, consente lievi modifiche nei valori di denominazione e restituzione (come hai fatto per Encode) e invia con una singola chiamata.

Problemi correlati