Struc exists to pack and unpack C-style structures from bytes, which is useful for binary files and network protocols. It could be considered an alternative to encoding/binary
, which requires massive boilerplate for some similar operations.
Take a look at an example comparing struc
and encoding/binary
Struc considers usability first. That said, it does cache reflection data and aims to be competitive with encoding/binary
struct packing in every way, including performance.
type Example struct {
Var int `struc:"int32,sizeof=Str"`
Str string
Weird []byte `struc:"[8]int64"`
Var []int `struc:"[]int32,little"`
}
Var []int `struc:"[]int32,little,sizeof=StringField"`
will pack Var as a slice of little-endian int32, and link it as the size of StringField
.sizeof=
: Indicates this field is a number used to track the length of a another field. sizeof
fields are automatically updated on Pack()
based on the current length of the tracked field, and are used to size the target field during Unpack()
.big
(default)little
pad
- this type ignores field contents and is backed by a [length]byte
containing nullsbool
byte
int8
, uint8
int16
, uint16
int32
, uint32
int64
, uint64
float32
float64
Types can be indicated as arrays/slices using []
syntax. Example: []int64
, [8]int32
.
Bare slice types (those with no [size]
) must have a linked Sizeof
field.
Private fields are ignored when packing and unpacking.
package main
import (
"bytes"
"github.com/lunixbochs/struc"
)
type Example struct {
A int `struc:"big"`
// B will be encoded/decoded as a 16-bit int (a "short")
// but is stored as a native int in the struct
B int `struc:"int16"`
// the sizeof key links a buffer's size to any int field
Size int `struc:"int8,little,sizeof=Str"`
Str string
// you can get freaky if you want
Str2 string `struc:"[5]int64"`
}
func main() {
var buf bytes.Buffer
t := &Example{1, 2, 0, "test", "test2"}
err := struc.Pack(&buf, t)
o := &Example{}
err = struc.Unpack(&buf, o)
}
BenchmarkEncode
uses struc. Stdlib
benchmarks use equivalent encoding/binary
code. Manual
encodes without any reflection, and should be considered an upper bound on performance (which generated code based on struc definitions should be able to achieve).
BenchmarkEncode 1000000 1265 ns/op
BenchmarkStdlibEncode 1000000 1855 ns/op
BenchmarkManualEncode 5000000 284 ns/op
BenchmarkDecode 1000000 1259 ns/op
BenchmarkStdlibDecode 1000000 1656 ns/op
BenchmarkManualDecode 20000000 89.0 ns/op
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。