为什么这两个结构体不相等?

huangapple go评论73阅读模式
英文:

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时,它们看起来是相等的。但为什么它们的表示形式是0xc2080004f80xc2080004b8,而我在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

它们不相等,因为它比较的是指针而不是指针的值。
你有几个选项。

  1. 不使用指针,也不能在结构体中使用切片,可以使用固定大小的数组。
  2. 编写自己的 func (p *packet) Equals(o *packet) bool 函数,并自行比较内容。
  3. 使用 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)
}

<kbd>playground</kbd>

英文:

They aren't equal because it's comparing the pointer not the value of the pointer.
You have few options.

  1. Don't use pointers and you won't be able to use slices either in either structs, you can use fixed size arrays.
  2. Write your own func (p *packet) Equals(o *packet) bool and compare stuff yourself.
  3. 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 &amp;&amp; o != nil &amp;&amp;
		h.dataLength == o.dataLength &amp;&amp;
		h.optDataLength == o.optDataLength &amp;&amp;
		h.packetType == o.packetType
}

func (p *packet) Equal(o *packet) bool {
	return p != nil &amp;&amp; o != nil &amp;&amp;
		p.header.Equal(o.header) &amp;&amp;
		p.syncByte == o.syncByte &amp;&amp;
		p.headerCrc == o.headerCrc &amp;&amp;
		p.dataCrc == o.dataCrc &amp;&amp;
		bytes.Equal(p.data, o.data) &amp;&amp;
		bytes.Equal(p.optData, o.optData)
}

<kbd>playground</kbd>

答案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.

huangapple
  • 本文由 发表于 2014年9月20日 04:17:36
  • 转载请务必保留本文链接:https://go.coder-hub.com/25941791.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定