-1

I know there are questions like this already: How do I convert [Size]byte to string in Go?, but my questions is "how do I convert []byte WITH ZERO VALUES to string"

package main

import (
    "fmt"
    "strings"
)

func main() {
    a := make([]byte, 16)

    r := strings.NewReader("test")
    _, _ = r.Read(a)

    b := "test"

    fmt.Println(string(a), b)
    fmt.Println(string(a) == b)
    fmt.Println(len(string(a)), len(b))
    fmt.Println(a, []byte(b))
}

The code above prints:

test test
false
16 4
[116 101 115 116 0 0 0 0 0 0 0 0 0 0 0 0] [116 101 115 116]

As you can see the zero values in a caused inequality between a and b, how should I treat them? How can I compare the two correctly?

super
  • 12,335
  • 2
  • 19
  • 29
Kacifer
  • 1,334
  • 17
  • 26
  • 4
    Those are not *empty*. Zero is still a value. But if you want to remove trailing zeros, just make a slice of the appropriate length, using the same array as its backing store, using the slice operation: `aShortened := a[:len]`. (Note that the `Read` operation *returns a length* and you should probably *save it* rather than throwing it away. It also returns an error, which you should check.) – torek May 06 '21 at 04:13
  • 1
    You probably should take the Tour of Go for basic language fundamentals like how slices work, what zero values are and how an io.Reader's Read method works. – Volker May 06 '21 at 04:40
  • Thanks @torek, the length helps to slice the array! – Kacifer May 06 '21 at 05:56
  • 1
    Don't edit an answer into your question. – super May 06 '21 at 06:53

2 Answers2

1

When you declare your slice a:

a := make([]byte, 16)

All of the elements are initialised with the "zero value" of a byte which is 0.

You can consider the slice full, for all intents and purposes. You are free to overwrite it in full, or partially, but it will always be a 16 element slice with a value at each index.

If you want to trim the zero values from the end of the slice, you could do that:

func trim(a []byte) []byte {
  for i := len(a) - 1; i >= 0; i-- {
    if a[i] != 0 {
      // found the first non-zero byte
      // return the slice from start to the index of the first non-zero byte
      return a[:i+1]
    }
  }

  // didn't find any non-zero bytes just return an empty slice
  return []byte{}
}

And then compare:

string(trim(a)) == b
Matt
  • 3,677
  • 1
  • 14
  • 24
1

The length returned by Read helps to slice the array:

a := make([]byte, 16)

r := strings.NewReader("test")
l, _ = r.Read(a)

b := "test"

fmt.Println(string(a[:l]) == b)) // true, they are equal!

Thanks @torek

Kacifer
  • 1,334
  • 17
  • 26