samol
samol

Reputation: 20570

Golang: How to printf % x for bytes in a struct?

var b [88]byte
n, err := file.Read(b[:])
fmt.Printf("bytes read: %d Bytes: [% x]\n", n, b)

The above prints bytes in hexdecimal

I have a struct like this

type SomeStruct struct {
   field1 []byte
   field2 []byte
}
someStructInstance := SomeStruct{[249 190 180 217], [29 1 0 0]}
fmt.Println(someStructInstance)
=> {[249 190 180 217] [29 1 0 0]}

But ideally I would like it to print hexdecimal

=> {[f9 be b4 d9] [1d 01 00 00]}

How would I go about that?

Upvotes: 6

Views: 24879

Answers (2)

zmb
zmb

Reputation: 7867

You could use reflection to inspect the struct and print any []bytes that it has.

package main

import (
    "fmt"
    "reflect"
)

type SomeStruct struct {
    field1 []byte
    field2 []byte
}

type OtherStruct struct {
    intValue  int
    intSlice  []int
    byteSlice []byte
}

var typeOfBytes = reflect.TypeOf([]byte(nil))

func printSlicesHex(obj interface{}) {
    value := reflect.ValueOf(obj)
    typeOfObj := value.Type()
    for i := 0; i < value.NumField(); i++ {
        field := value.Field(i)
        if field.Type() == typeOfBytes {
            bytes := field.Bytes()
            printBytes(typeOfObj.Field(i).Name, bytes)
        }
    }
}

func printBytes(name string, bytes []byte) {
    fmt.Printf("%s: [% x]\n", name, bytes)
}

func main() {
    someStructInstance := SomeStruct{[]byte{249, 190, 180, 217}, []byte{29, 1, 0, 0}}
    fmt.Println("Printing []bytes in SomeStruct")
    printSlicesHex(someStructInstance)
    fmt.Println()

    otherStruct := OtherStruct{0, []int{0, 1, 2}, []byte{0, 1, 2, 3}}
    fmt.Println("Printing []bytes in OtherStruct")
    printSlicesHex(otherStruct)
}

For each []byte, this example prints the name of the field and its data (in hex). You could improve on this by taking a custom function to do the printing, so you don't always have to print in hex.

Playground Link

Upvotes: 3

David Grayson
David Grayson

Reputation: 87386

I think you will just have to define your own String function on SomeStruct. Here is an example:

package main

import "fmt"

type SomeStruct struct {
   field1 []byte
   field2 []byte
}

func (s SomeStruct) String() string {
  return fmt.Sprintf("{[% x] [% x]}", s.field1, s.field2)
}

func main() {
  someStructInstance := SomeStruct{[]byte{249, 190, 180, 217}, []byte{29, 1, 0, 0}}
  fmt.Println(someStructInstance)
}

See it in running on the Go Playground: http://play.golang.org/p/eYBa1n33a2

Upvotes: 5

Related Questions