2010-01-29 12 views
2

J'essaye d'encoder un grand nombre à une liste d'octets (uint8 dans Go). Le nombre d'octets est inconnu, donc je voudrais utiliser le vecteur. Mais Go ne fournit pas de vecteur d'octet, que puis-je faire? Et est-il possible d'obtenir une tranche d'un tel vecteur d'octets?Avec Go, comment ajouter un nombre inconnu d'octets dans un vecteur et obtenir une tranche d'octets?

J'ai l'intention d'implémenter la compression de données. Au lieu de stocker des petits et grands nombres avec le même nombre d'octets, J'implémente une variable octets qui utilise moins d'octets avec un petit nombre et plus d'octets avec un grand nombre.

Mon code ne peut pas compiler, affirmation de type non valide:

1 package main 
    2 
    3 import (
    4  //"fmt" 
    5  "container/vector" 
    6) 
    7 
    8 func vbEncodeNumber(n uint) []byte{ 
    9  bytes := new(vector.Vector) 
10  for { 
11   bytes.Push(n % 128) 
12   if n < 128 { 
13    break 
14   } 
15   n /= 128 
16  } 
17  bytes.Set(bytes.Len()-1, bytes.Last().(byte)+byte(128)) 
18  return bytes.Data().([]byte) // <- 
19 } 
20 
21 func main() { vbEncodeNumber(10000) } 

Je souhaite écrit beaucoup de code comme dans un fichier binaire, donc je souhaite le func peut revenir tableau d'octets.

Je n'ai pas trouvé d'exemple de code sur un vecteur.

+0

En fait, je trouve que je peux utiliser la fonction bytes.Add pour répondre à mes besoins. Il n'est pas nécessaire d'utiliser un vecteur du tout. –

Répondre

2

Puisque vous essayez de représenter de grands nombres, vous pourriez voir si le gros paquet remplit vos objectifs.

La structure vectorielle générale peut être utilisée pour stocker des octets. Il accepte une interface vide comme son type, et tout autre type satisfait cette interface. Vous pouvez récupérer une tranche d'interfaces via la méthode Data, mais il n'existe aucun moyen de la convertir en une tranche d'octets sans la copier. Vous ne pouvez pas utiliser l'assertion de type pour transformer une tranche d'interface {} en tranche d'autre chose. Il faudrait faire quelque chose comme ce qui suit à la fin de votre fonction: (je ne l'ai pas essayé de compiler ce code parce que je ne peux pas en ce moment)

byteSlice = make([]byte, bytes.Len()) 
for i, _ := range byteSlice { 
    byteSlice[i] = bytes.At(i).(byte) 
} 
return byteSlice 
2

Jetez un oeil à l'ensemble d'octets et la Type de tampon là. Vous pouvez écrire vos ints sous forme d'octets dans le tampon, puis vous pouvez utiliser la méthode Bytes() pour accéder aux tranches d'octets du tampon.

1

J'ai trouvé que les vecteurs étaient beaucoup moins utiles puisque l'ajout générique et la copie ont été ajoutés au langage. Voici comment je le ferais en un coup avec moins de copie:

package main 

import "fmt" 

func vbEncodeNumber(n uint) []byte { 
    bytes := make([]byte, 0, 4) 
    for n > 0 { 
     bytes = append(bytes, byte(n%256)) 
     n >>= 8 
    } 
    return bytes 
} 

func main() { 
    bytes := vbEncodeNumber(10000) 
    for i := len(bytes)-1; i >= 0 ; i-- { 
     fmt.Printf("%02x ", bytes[i]) 
    } 
    fmt.Println("") 
}