0

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?

4
  • 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.) Commented May 6, 2021 at 4: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. Commented May 6, 2021 at 4:40
  • Thanks @torek, the length helps to slice the array! Commented May 6, 2021 at 5:56
  • 1
    Don't edit an answer into your question. Commented May 6, 2021 at 6:53

2 Answers 2

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

Sign up to request clarification or add additional context in comments.

Comments

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.