英文:
why are those two structs not equal?
问题
我在Go语言中有一个结构体:
type header struct {
dataLength uint16
optDataLength uint8
packetType uint8
}
type packet struct {
syncByte uint8
header *header
headerCrc uint8
data []byte
optData []byte
dataCrc uint8
}
我已经创建了一个用于创建数据包和将其编码为二进制的Encode和Decode函数。但是为什么这两个instances.header
实例不同?
&{syncByte:85 header:0xc2080004b8 headerCrc:112 data:[2] optData:[] dataCrc:14}
&{syncByte:85 header:0xc2080004f8 headerCrc:112 data:[2] optData:[] dataCrc:14}
如果我在这两个header上运行Println,我得到:
&{dataLength:1 optDataLength:0 packetType:5}
&{dataLength:1 optDataLength:0 packetType:5}
在我直接检查packet.header时,它们看起来是相等的。但为什么它们的表示形式是0xc2080004f8
和0xc2080004b8
,而我在packet.header上检查时看不到任何区别呢?
英文:
I have a struct in go:
type header struct {
dataLength uint16
optDataLength uint8
packetType uint8
}
type packet struct {
syncByte uint8
header *header
headerCrc uint8
data []byte
optData []byte
dataCrc uint8
}
If i have created an Encode and Decode function for creating packages and for encoding them into binary. However why does those two instances.header differ?
&{syncByte:85 header:0xc2080004b8 headerCrc:112 data:[2] optData:[] dataCrc:14}
&{syncByte:85 header:0xc2080004f8 headerCrc:112 data:[2] optData:[] dataCrc:14}
If i run Println on those two header's i get:
&{dataLength:1 optDataLength:0 packetType:5}
&{dataLength:1 optDataLength:0 packetType:5}
which to mee seems equal. But why do they look like 0xc2080004f8 vs 0xc2080004b8 when i cannot see the difference when i check on packet.header directly?
答案1
得分: 2
它们不相等,因为它比较的是指针而不是指针的值。
你有几个选项。
- 不使用指针,也不能在结构体中使用切片,可以使用固定大小的数组。
- 编写自己的
func (p *packet) Equals(o *packet) bool
函数,并自行比较内容。 - 使用
reflect.DeepEqual
,这是最慢/效率最低的解决方案,我个人会选择 #2。
#2 的简单实现:
func (h *header) Equal(o *header) bool {
return h != nil && o != nil &&
h.dataLength == o.dataLength &&
h.optDataLength == o.optDataLength &&
h.packetType == o.packetType
}
func (p *packet) Equal(o *packet) bool {
return p != nil && o != nil &&
p.header.Equal(o.header) &&
p.syncByte == o.syncByte &&
p.headerCrc == o.headerCrc &&
p.dataCrc == o.dataCrc &&
bytes.Equal(p.data, o.data) &&
bytes.Equal(p.optData, o.optData)
}
英文:
They aren't equal because it's comparing the pointer not the value of the pointer.
You have few options.
- Don't use pointers and you won't be able to use slices either in either structs, you can use fixed size arrays.
- Write your own
func (p *packet) Equals(o *packet) bool
and compare stuff yourself. - use
reflect.DeepEqual
, this is by far the slowest / least efficient solution, I'd personally go with #2.
Simple implementation of #2:
func (h *header) Equal(o *header) bool {
return h != nil && o != nil &&
h.dataLength == o.dataLength &&
h.optDataLength == o.optDataLength &&
h.packetType == o.packetType
}
func (p *packet) Equal(o *packet) bool {
return p != nil && o != nil &&
p.header.Equal(o.header) &&
p.syncByte == o.syncByte &&
p.headerCrc == o.headerCrc &&
p.dataCrc == o.dataCrc &&
bytes.Equal(p.data, o.data) &&
bytes.Equal(p.optData, o.optData)
}
答案2
得分: 1
每次调用Decode
都会分配一个新的header
类型的值。您观察到了这些分配的头部的不同地址。这两个头部的值具有相同的内容,但它们位于不同的地址上。
英文:
Each call to Decode
allocates a new value of type header
. You are observing the different addresses for these allocated headers. The two headers values have the same contents, but they are at different addresses.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论