【问题标题】:Why the binary.Size() return (-1)?为什么 binary.Size() 返回 (-1)?
【发布时间】:2024-04-23 09:25:01
【问题描述】:

代码sn-p喜欢这样:

package main
import (
    "fmt"
    "encoding/binary"
    "reflect"
)

const (
    commandLen = 1
    bufLen int = 4
)

func main(){
    fmt.Printf("%v %v\n", reflect.TypeOf(commandLen), reflect.TypeOf(bufLen))
    fmt.Printf("%d %d", binary.Size(commandLen), binary.Size(bufLen))
}

输出是:

int int
-1 -1

我认为由于 commandLen 和 bufLen 的类型是 int 的,并且来自“用 golang 编程”, int 应该是 int32 或 int64,这取决于实现,所以我认为 binary.Size() 应该返回一个值,而不是 (-1)。

为什么 binary.Size() 返回 (-1)?

【问题讨论】:

    标签: go


    【解决方案1】:

    tl;博士

    int 不是定长类型,所以它不起作用。使用具有固定长度的内容,例如int32

    说明

    这可能看起来像一个错误,但它实际上不是一个错误。 documentation of Size() 说:

    Size 返回 Write 将生成多少字节来对值 v 进行编码,该值必须是 a
    固定大小的值或固定大小的值的切片,或指向此类数据的指针。

    固定大小的值是不依赖于架构且大小已知的值 预先。 int32int64 是这种情况,但 int 不是这种情况,因为它取决于 环境的架构。请参阅documentation of int

    如果您问自己为什么 Size() 会强制执行此操作,请考虑在您的 64 位机器并在远程 32 位机器上解码数据。这只有在您有长度编码类型时才有可能,int 不是。因此,您要么必须将大小与类型一起存储,要么强制执行开发人员所做的固定长度类型。

    这反映在计算大小的encoding/binarysizeof() 函数中:

    case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64,
           reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
           reflect.Float32, reflect.Float64, reflect.Complex64, reflect.Complex128:
           return int(t.Size()), nil
    

    如您所见,除了reflect.Int 之外,列出了所有数字类型。

    【讨论】: