Convert string to FIXED byte array

5,672 views
Skip to first unread message

Damian

unread,
May 22, 2011, 7:08:54 PM5/22/11
to golang-nuts
myarray []byte = []byte("hello world")

This works fine..


myarray [20]byte = []byte("hello world")

This doesn't - because i specify a size of the array - is this a BUG
or
am i doing it wrong? I need to be able to store a string in
a fixed byte array.

Evan Shaw

unread,
May 22, 2011, 7:18:04 PM5/22/11
to Damian, golang-nuts

This isn't a bug. You're trying to assign a slice value to an array
variable. The language doesn't allow converting a string or a slice to
an array.

Why do you need to store a string in an array instead of a slice?

- Evan

Dmitry Chestnykh

unread,
May 22, 2011, 7:28:41 PM5/22/11
to golan...@googlegroups.com
You can't convert a 11-byte string to a 20-byte array. You can, however, convert a 20-byte string to a 20-byte array:

    var myarray [20]byte = [...]byte("hello world of array")

But you probably don't need this.
Also, there's no such thing as fixed array. Arrays are arrays, slices are slices.

-Dmitry

Evan Shaw

unread,
May 22, 2011, 7:35:22 PM5/22/11
to golan...@googlegroups.com
On Mon, May 23, 2011 at 11:28 AM, Dmitry Chestnykh <dch...@gmail.com> wrote:
>     var myarray [20]byte = [...]byte("hello world of array")

That works, but I'm not sure it's actually supposed to. The spec
doesn't say anything about it that I can find.

- Evan

Dmitry Chestnykh

unread,
May 22, 2011, 7:35:33 PM5/22/11
to golan...@googlegroups.com
I used the word "convert" incorrectly in my reply. As Evan said, you can't convert a slice to array in runtime. This thing: [...]byte("hello world of array") creates a 20-byte array.

-Dmitry

peterGo

unread,
May 22, 2011, 7:36:50 PM5/22/11
to golang-nuts
Damien,

It's not a bug. Are you sure you really need to do this? Here's one
way.

package main

import (
"fmt"
)

func main() {
var a [20]byte
copy(a[:], []byte("hello world"))
fmt.Println(string(a[:]))
}

Peter

Brad Fitzpatrick

unread,
May 22, 2011, 7:38:23 PM5/22/11
to Evan Shaw, golang-nuts
From the spec: The notation ... specifies an array length equal to the maximum element index plus one.

So that _is_ supposed to work. The [...] just means "it's an array, not a slice, but you count for me".

Dmitry Chestnykh

unread,
May 22, 2011, 7:40:49 PM5/22/11
to golan...@googlegroups.com
Yeah,  specifying size doesn't work [20]byte("hello world of array"):

   cannot convert "hello world of array" (type string) to type [20]uint8

So [...] shouldn't work :-)

-Dmitry

Evan Shaw

unread,
May 22, 2011, 7:42:20 PM5/22/11
to Brad Fitzpatrick, golang-nuts

Right, I understand what [...] means. I'm just not sure that
[...]byte(...) is actually an array literal. It looks more like a
conversion where the value happens to be statically known.

- Evan

Damian

unread,
May 22, 2011, 7:43:46 PM5/22/11
to golang-nuts
type UserMsg struct {
UName [20]byte
Ident int32
X int32
Y int32
}

I have a few structs similar to this - they contain a fixed byte array
(to hold a string variable). I want to send these structs over TCP or
UDP.

...

Well that was my initial goal, but now i see doing things this way has
some serious design issues in Go - since i'll also have trouble
casting
a struct to []byte.

On May 23, 12:18 am, Evan Shaw <eds...@gmail.com> wrote:

peterGo

unread,
May 22, 2011, 7:45:41 PM5/22/11
to golang-nuts
Evan,

> That works, but I'm not sure it's actually supposed to. The spec
> doesn't say anything about it that I can find.

"The notation ... specifies an array length equal to the maximum
element index plus one."

Composite literals
http://golang.org/doc/go_spec.html#Composite_literals

Peter

Evan Shaw

unread,
May 22, 2011, 7:48:28 PM5/22/11
to peterGo, golang-nuts
On Mon, May 23, 2011 at 11:45 AM, peterGo <go.pe...@gmail.com> wrote:
> Composite literals
> http://golang.org/doc/go_spec.html#Composite_literals

Yes, but what I'm saying is that:

[...]byte("hello world")

is not a composite literal. It's a conversion. A composite literal would be:

[...]byte{'h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd'}

- Evan

Evan Shaw

unread,
May 22, 2011, 7:53:19 PM5/22/11
to Damian, golang-nuts
On Mon, May 23, 2011 at 11:43 AM, Damian <damian...@gmail.com> wrote:
> type UserMsg struct {
>    UName [20]byte
>    Ident int32
>    X int32
>    Y int32
> }
>
> I have a few structs similar to this - they contain a fixed byte array
> (to hold a string variable). I want to send these structs over TCP or
> UDP.
>
> ...
>
> Well that was my initial goal, but now i see doing things this way has
> some serious design issues in Go - since i'll also have trouble
> casting
> a struct to []byte.

It's possible to cast a struct to a []byte with package unsafe, but,
well, it's unsafe. :) Another possibility is using the encoding/binary
package, although it's quite a bit slower than the unsafe way.

- Evan

Steven

unread,
May 22, 2011, 8:10:02 PM5/22/11
to Evan Shaw, Damian, golang-nuts

Also, if you don't care about having a fixed width encoding, you can
use gob. It's type safe.

Dmitry Chestnykh

unread,
May 22, 2011, 8:13:24 PM5/22/11
to golan...@googlegroups.com
I'd say just copy the string contents into it... However, if you want to to convert a string into 20-byte array without thinking about it, it's most likely a bug. If my username is "Дмитрий Честных" and you store it as 20 bytes, my name would be "Дмитрий Че�". You just can't cut it to exactly 20 bytes. Probably, you'd cut it to "Дмитрий Че" (19 bytes), and 20th byte would be some filler (like 0). In any case, you have to do the conversion manually to get the correct result.

-Dmitry

Steven

unread,
May 22, 2011, 8:27:00 PM5/22/11
to golan...@googlegroups.com
On Sun, May 22, 2011 at 8:13 PM, Dmitry Chestnykh <dch...@gmail.com> wrote:
I'd say just copy the string contents into it... However, if you want to to convert a string into 20-byte array without thinking about it, it's most likely a bug. If my username is "Дмитрий Честных" and you store it as 20 bytes, my name would be "Дмитрий Че�". You just can't cut it to exactly 20 bytes. Probably, you'd cut it to "Дмитрий Че" (19 bytes), and 20th byte would be some filler (like 0). In any case, you have to do the conversion manually to get the correct result.

-Dmitry

You can just use copy, and then (if necessary) check that n == len(str), though if you're doing this with literals, you probably already know if the lengths work out.

Dmitry Chestnykh

unread,
May 23, 2011, 1:20:36 AM5/23/11
to golan...@googlegroups.com
BTW, if you want to cast a struct to []byte, you have another design mistake, which Go helpfully prevents you from doing by not having such casts (without unsafe package): endianness. How do you like your int32s, in little endian or in big endian?

-Dmitry

Confunctionist

unread,
May 23, 2011, 3:19:35 PM5/23/11
to golan...@googlegroups.com
In Learning Go, I had to play a bit with []byte arrays and slices to overcome my loathsome intuition.  Here are two snippets that might help.

package main
// var arr []float64
func main() {
a := []float64{1, 3, 5}
// b := arr         // compiles, doesn't run with var arr []float64
// b := new([]float64) // doesn't compile, doesn't run
// b := make([]float64) // doesn't compile, doesn't run
// var b []float64 // compiles, doesn't run
// b := [...]float64 { 0.0 }         // compiles, doesn't run
b := [...]float64 { 0.0, 0, 0 } // compiles, runs
// b := make([]float64, len(a)) // compiles, runs
for i, _ := range a { b[i] = a[i] }
for _,v  := range b { print(v," ") }

}

package main
var arr []float64
var crr [2]float64
func foo( a []float64) { println(a) }
func main() {
foo(arr)
brr := []float64 { 2.0 }
foo(brr)
// foo(crr) // doesn't compile
crrsl := crr
// foo(crrsl) // doesn't compile
drr := arr
copy(drr[:], brr) 
foo(drr)
arr = append(arr, 2.0)
foo(arr)
arrsl := arr
foo(arrsl)
// crrsl = drr // doesn't compile
println(crrsl[0])
}

Steven

unread,
May 23, 2011, 4:06:05 PM5/23/11
to golan...@googlegroups.com

Sorry, I misread. You'd have to do something like: http://goo.gl/YWin7

Dmitry Chestnykh

unread,
May 23, 2011, 4:23:42 PM5/23/11
to golan...@googlegroups.com
On Monday, May 23, 2011 10:06:05 PM UTC+2, Steven wrote:

Sorry, I misread. You'd have to do something like: http://goo.gl/YWin7

Yep.
 
-Dmitry
Reply all
Reply to author
Forward
0 new messages