0

I am trying to make a global byte array from a string with:

point := []byte{0x23f32...}

But I am getting the error:

untyped string constant "0x23f32...) as byte value in array or slice literal

I know what I should use a type conversion to convert a string to a slice of bytes, i.e. use of () instead of {}.

point := []byte(0x23f32...) 

The code in the question is a composite literal. However, I am using operators as a global variable, so I think that I cannot declare the variable that way. Also, further in the code, logically, I will also have to use [33]byte, so I'm worried about how to declare point []byte here so that I don't have a type error later like "mismatched types [32]byte and []byte".

So keeping these two questions in mind, could you please tell me how to deal with point := []byte here correctly?

John Kugelman
  • 349,597
  • 67
  • 533
  • 578

2 Answers2

1

0x23f32... is a integer literal and won't convert to a byte (or bytes). You will get this compile-time error for var point = []byte{0x23f32}

cannot use 0x23f32 (untyped int constant 147250) as byte value in array or slice literal (overflows)

Assuming that what you expect to get (it's not clear from your question) from something like

point := []byte{0x23f32 . . . }

is essentially

point := []byte{0x23,0xf3,0x2? . . . }

...

First, if you are trying to declare a "global" variable (e.g. a package-scoped variable), you need to use the var <name> <type> = <value> form. You can't use <name> := <value>.

Second, you can initialize a []byte in a couple different ways:

  • var p1 []byte = []byte{ 0x12, 0x23, 0x45, . . . }
    an array/slice of hex constants, each needs to be in the range 0x00-0xFF (0-255 decimal).

  • var p2 []byte = []byte{ "\x12\x23\x45 . . ." }
    a string containing the desired bytes.

  • var p3 []byte = []byte{ 18, 35, 69 . . . }
    an array/slice of decimal constants

  • var p4 []byte = []byte{ '\x12', '\x23', '\x45' . . . }
    an array slice of individual byte literals. Note that if one specifies a value outside the range of a byte (0x00–0xFF, 0-255 decimal), you'll get a compile time error along the lines of:

    cannot use 'ш' (untyped rune constant 1096) as byte value in array or slice literal (overflows)

Note that the above 4 examples all yield exactly the same value.

Nicholas Carey
  • 71,308
  • 16
  • 93
  • 135
  • hello Nicholas, thanks for detailed answer! i think byte{ 0x12, 0x23, 0x45} is that i need. can I please ask another question: and if it is still permissible for me to use point not as a global variable, is it possible for me in this case to use just point := []byte(0x23f32...) type conversion to convert a string to a slice of bytes? I will get the same result as in the case of array/slice of hex constants { 0x12, 0x23 ... ? – thereisnoalternativeDEAF Sep 30 '22 at 22:44
  • the value `0x23f32...` being cast as a `[]byte` here: `point := []byte(0x23f32...)`, is not a string: it is a hexadecimal (base-16) integer literal. It will be limited to no more than 16 hexadecimal digits (the maximum for a 64-bit integer type). If it's longer than 16 digits, something like `n int64 = 0x0123456789abcdef0123456789abcdef` will generate the compile time error `cannot use 0x0123456789abcdef0123456789abcdef (untyped int constant 1512366075204170929049582354406559215) as int64 value in variable declaration (overflows)` – Nicholas Carey Sep 30 '22 at 22:57
  • but due type conversion, it would be slice of bytes? i just checked this out with byte(), it's work as i expected – thereisnoalternativeDEAF Sep 30 '22 at 23:40
0

If you need to convert 32 bit number to bytes, you can do this:

package main

import (
   "encoding/binary"
   "fmt"
)

func main() {
   var point [4]byte
   binary.BigEndian.PutUint32(point[:], 0x23f32)
   fmt.Println(point) // [0 2 63 50]
}

https://godocs.io/encoding/binary#ByteOrder.PutUint32

  • Hey 048, thanks for the answer, really appreciate that! but here the problem - if I use 0x23 then everything is ok. but actually I need to use 32 bytes long value, so i get the following error point := []byte{0x23f32 ...} // > 0x23f32 ... to 32 byte long 'cannot use 0x23f32 ... (untyped int constant 147250 ... ) as byte value in array or slice literal (overflows)' – thereisnoalternativeDEAF Sep 30 '22 at 22:31
  • sorry i didn't quite understand what you mean by Rust float literals mixed up with Go., I mean f32 in example is just a continuation of 32 bytes, for example 0x23f32a324f12c3 ... etc., not a float literal, or are you pointing to something else? – thereisnoalternativeDEAF Sep 30 '22 at 22:35
  • @thereisnoalternativeDEAF see update –  Sep 30 '22 at 22:38
  • thanks! I'm trying to check it out now – thereisnoalternativeDEAF Sep 30 '22 at 23:34