英文:
Why the binary.Size() return (-1)?
问题
代码片段如下:
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
,根据《Go语言编程》一书,int
的具体大小取决于实现,可能是int32
或int64
。因此,我认为binary.Size()
应该返回一个值,而不是-1
。
为什么binary.Size()
返回-1
呢?
英文:
The code snippet likes this:
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))
}
And the output is:
int int
-1 -1
I think since the types of commandLen and bufLen are int, and from "Programming in golang",
the int should be int32 or int64 which depending on the implementation, so I think the binary.Size() should return a value, not (-1).
Why the binary.Size() return (-1)?
答案1
得分: 3
tl;dr
int
不是固定长度的类型,所以它不起作用。使用具有固定长度的类型,例如int32
。
解释
这看起来可能像是一个bug,但实际上并不是bug。Size()
的文档中写道:
> Size返回编码值v所需生成的字节数,v必须是固定大小的值或固定大小值的切片,或指向这些数据的指针。
固定大小的值是指不依赖于架构且大小事先已知的值。这适用于int32
或int64
,但不适用于int
,因为它取决于环境的架构。请参阅int
的文档。
如果你想知道为什么Size()
要强制执行这个规定,考虑在64位机器上对int
进行编码,然后在远程的32位机器上解码数据。只有当你有长度编码类型时,这才是可能的,而int
不是长度编码类型。所以你要么将大小与类型一起存储,要么强制使用固定长度的类型,这是开发人员所做的。
这反映在encoding/binary
包的sizeof()
函数中计算大小的方式:
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
。
英文:
tl;dr
int
is not a fixed-length type, so it won't work. Use something that has a fixed length, for example int32
.
Explanation
This might look like a bug but it is actually not a bug. The documentation of Size()
says:
> Size returns how many bytes Write would generate to encode the value v, which must be a
> fixed-size value or a slice of fixed-size values, or a pointer to such data.
A fixed-size value is a value that is not dependent on the architecture and the size is known
beforehand. This is the case for int32
or int64
but not for int
as it depends on the
environment's architecture. See the documentation of int
.
If you're asking yourself why Size()
enforces this, consider encoding an int
on your
64 bit machine and decoding the data on a remote 32 bit machine. This is only possible if you have length encoded types, which int
is not. So you either have to store the size along with the type or enforce fixed-length types which the developers did.
This is reflected in the sizeof()
function of encoding/binary
that computes the size:
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
As you can see, there are all number types listed but reflect.Int
.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论