代码拉取完成,页面将自动刷新
// structlayout displays the layout (field sizes and padding) of structs.
package main
import (
"encoding/json"
"flag"
"fmt"
"go/build"
"go/types"
"log"
"os"
"honnef.co/go/tools/gcsizes"
st "honnef.co/go/tools/structlayout"
"honnef.co/go/tools/version"
"golang.org/x/tools/go/loader"
)
var (
fJSON bool
fVersion bool
)
func init() {
flag.BoolVar(&fJSON, "json", false, "Format data as JSON")
flag.BoolVar(&fVersion, "version", false, "Print version and exit")
}
func main() {
log.SetFlags(0)
flag.Parse()
if fVersion {
version.Print()
os.Exit(0)
}
if len(flag.Args()) != 2 {
flag.Usage()
os.Exit(1)
}
conf := loader.Config{
Build: &build.Default,
}
var pkg string
var typName string
pkg = flag.Args()[0]
typName = flag.Args()[1]
conf.Import(pkg)
lprog, err := conf.Load()
if err != nil {
log.Fatal(err)
}
var typ types.Type
obj := lprog.Package(pkg).Pkg.Scope().Lookup(typName)
if obj == nil {
log.Fatal("couldn't find type")
}
typ = obj.Type()
st, ok := typ.Underlying().(*types.Struct)
if !ok {
log.Fatal("identifier is not a struct type")
}
fields := sizes(st, typ.(*types.Named).Obj().Name(), 0, nil)
if fJSON {
emitJSON(fields)
} else {
emitText(fields)
}
}
func emitJSON(fields []st.Field) {
if fields == nil {
fields = []st.Field{}
}
json.NewEncoder(os.Stdout).Encode(fields)
}
func emitText(fields []st.Field) {
for _, field := range fields {
fmt.Println(field)
}
}
func sizes(typ *types.Struct, prefix string, base int64, out []st.Field) []st.Field {
s := gcsizes.ForArch(build.Default.GOARCH)
n := typ.NumFields()
var fields []*types.Var
for i := 0; i < n; i++ {
fields = append(fields, typ.Field(i))
}
offsets := s.Offsetsof(fields)
for i := range offsets {
offsets[i] += base
}
pos := base
for i, field := range fields {
if offsets[i] > pos {
padding := offsets[i] - pos
out = append(out, st.Field{
IsPadding: true,
Start: pos,
End: pos + padding,
Size: padding,
})
pos += padding
}
size := s.Sizeof(field.Type())
if typ2, ok := field.Type().Underlying().(*types.Struct); ok && typ2.NumFields() != 0 {
out = sizes(typ2, prefix+"."+field.Name(), pos, out)
} else {
out = append(out, st.Field{
Name: prefix + "." + field.Name(),
Type: field.Type().String(),
Start: offsets[i],
End: offsets[i] + size,
Size: size,
Align: s.Alignof(field.Type()),
})
}
pos += size
}
if len(out) == 0 {
return out
}
field := &out[len(out)-1]
if field.Size == 0 {
field.Size = 1
field.End++
}
pad := s.Sizeof(typ) - field.End
if pad > 0 {
out = append(out, st.Field{
IsPadding: true,
Start: field.End,
End: field.End + pad,
Size: pad,
})
}
return out
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。