Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

encoding/binary: make type error clearer #4825

Closed
gopherbot opened this issue Feb 15, 2013 · 4 comments
Closed

encoding/binary: make type error clearer #4825

gopherbot opened this issue Feb 15, 2013 · 4 comments
Milestone

Comments

@gopherbot
Copy link

by shakeel.mahate:

According to godoc: "binary.Read reads structured binary data from r into data.
Data must be a pointer to a fixed-size value or a slice of fixed-size values."

You can ask binary.Read() to read a slice of structs which works, but if you have a
slice as a member of struct, it returns an error "binary.Read: invalid type "

This works:
type S struct {
  Index int32
  Ticks int32
  Analogs [3]int16
  Digitals [8]byte
}
s := make([]S, 1024) // Slice of S works
binary.Read(buf, binary.LittleEndian, s)

This does not work:
type S struct {
  Index int32
  Ticks int32
  Analogs []int16 // This is offending slice
  Digitals []byte // And so is this
}
s := make([]S, 1024)
for i := range s {
  s[i].Analogs = make([]int16, 3) // Create the backing store for slices
  s[i].Digitals = make([]byte, 8) // Ditto
}
binary.Read(buf, binary.LittleEndian, s) // Returns binary.Read: invalid type error
message

First of all the error message is very cryptic, because it is not clear why the read
failed. It would be better to point out the actual member that failed, S.Analogs

Secondly the syntax for array and slice are very similar and we are encouraged to think
of them as one and the same. But you can only define an array's length as a constant
expression, there is no way to specify the length of an array using non-const
expressions. http://golang.org/ref/spec#Constant_expressions

Since we truly cannot create non-const arrays, the binary.Read API should support slices
as members.

I really like the terseness and elegance of the binary.Read API, I create slice of
structs and ask read to populate it. I just wish that the structs itself could have a
slice as a member or provide a better error message.

I had to resort reading each member of the struct individually in order to work around
this problem

Work around:
var Index, Ticks int32
Analogs := make([]int16, 3)
Digitals := make([]byte, 8)
for i := range 1024 {
  binary.Read(buf, binary.LittleEndian, &Index)
  // move the buf+4
  binary.Read(buf, binary.LittleEndian, &Ticks)
  // move the buf+4
  binary.Read(buf, binary.LittleEndian, Analogs)
  // move the buf+(3*2)
  binary.Read(buf, binary.LittleEndian, Digitals)
  // move the buf+(8*1)
}


Go version 1.0.3
Windows 7
@rsc
Copy link
Contributor

rsc commented Feb 15, 2013

Comment 1:

structs containing slices are not fixed-size values: the size varies depending on the
size of the slice.
If you really only have 3 Analogs and 8 Digitals then you can use an array. If the
length is variable, then there are many possible ways to encode it, and encoding/binary
is not going to pick one. It is for fixed-size values.
For encoding of richer values, consider encoding/gob or encoding/json.

Status changed to WorkingAsIntended.

@gopherbot
Copy link
Author

Comment 2 by shakeel.mahate:

The example of 3 Analogs and 8 Digitals was just for ease of understanding. I am parsing
a Comtrade binary data file. http://en.wikipedia.org/wiki/Comtrade and the linkt to the
standard
http://ieeexplore.ieee.org/xpl/freeabs_all.jsp?tp=&arnumber=798772&isnumber=17337
The number of Analogs and Digitals is specified in the Config file. And I really dont
have control of how they do the encoding, I cannot force them to encode using gob or
json, I wish I could.
I really have a work around and everything works. It just was frustrating that the
runtime errors were not really helpful.
Since I do pass in a slice of structs with arrays and it works, but a slice of structs
with slices does not work, which is indeed working as designed.
I have a fixed size struct, but its size is not known as a constant expression. This is
the root problem.
Thanks for all your work and really elegant APIs, I like them and I am enjoying
programming in Go.

@rsc
Copy link
Contributor

rsc commented Feb 15, 2013

Comment 3:

We can definitely make the type error say the specific type.

Status changed to Accepted.

@rsc
Copy link
Contributor

rsc commented Feb 15, 2013

Comment 4:

This issue was closed by revision 2b9787c.

Status changed to Fixed.

@rsc rsc added this to the Go1.1 milestone Apr 14, 2015
@rsc rsc removed the go1.1maybe label Apr 14, 2015
@golang golang locked and limited conversation to collaborators Jun 24, 2016
This issue was closed.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

2 participants