Skip to content

Commit

Permalink
add #50
Browse files Browse the repository at this point in the history
  • Loading branch information
smallnest committed Apr 21, 2024
1 parent b9fb1cc commit bb179cf
Show file tree
Hide file tree
Showing 7 changed files with 32 additions and 1 deletion.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ Go tips from [Phuong Le](https://twitter.com/func25).
| 47 | Table-driven tests, subtests, and parallel tests | devin7788 |
| 48 | | |
| 49 | | |
| 50 | | |
| 50 | Make Structs Non-comparable. | smallnest |
| 51 | | |
| 52 | | |
| 53 | | |
Expand Down
30 changes: 30 additions & 0 deletions src/050.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Tip #50 使结构体不可比较

> 原始链接:[Golang Tip #50: Make Structs Non-comparable](https://twitter.com/func25/status/1768621711929311620)
>
在Go语言中,如果一个结构体中的每个字段都是可比较的,那么该结构体本身也是可比较的。这意味着你可以直接使用`==``!=`运算符来比较两个结构体:
![](./images/050/1.png)

但是,直接比较包含浮点数的结构体可能会有问题。理想情况下,浮点数值应该使用近似值进行比较。我们可能更希望团队成员使用自定义的`.Equals`方法进行比较:
![](./images/050/2.png)

但让我们面对现实,使用`p1 == p2`是直接、快速的,对于不了解浮点数比较细微差别的任何人来说都是很诱人的。为了确保每个开发人员都使用您的比较方法,这里有一个零成本的策略:
![](./images/050/3.jpeg)

`[0]func()` 有3个特性:
- 非导出的: 对于你的结构体的使用者来说是隐藏的。
- 零宽度(或无成本): 因为长度为0,所以这个数组在内存中不占用任何空间。
- 不可比较: func()是一个函数类型,而函数在Go中是不可比较的。

试图直接使用`==``!=`比较这种结构体的两个实例将触发编译时错误:
"invalid operation: a == b (struct containing [0]func() cannot be compared)"

**但是,请记住不要将[0]func()放在最后。**

虽然它不占用空间,但它的位置仍然可能影响我们结构体的大小:
![](./images/050/4.png)

关于字段对齐(和填充)的进一步理解,可以参考以下两个资源:
- tips#41:按从大到小的顺序排列结构体中的字段。(https://colobu.com/gotips/041.html)
- Go仓库中的Issue #9401: https://github.com/golang/go/issues/9401
1 change: 1 addition & 0 deletions src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
- [Tip #40 在使用defer时处理错误以防止静默失败](./040.md)
- [Tip #44 有意地使用Must函数来停止程序](./044.md)
- [Tip #47 表驱动测试,测试集和并行运行测试](./047.md)
- [Tip #50 使结构体不可比较](./050.md)
- [Tip #71 用泛型让 sync.Pool 类型安全](./071.md)
- [Tip #65 使用泛型返回指针](./065.md)
- [Tip #66 在fmt.Errorf中简化你的错误信息](./066.md)
Expand Down
Binary file added src/images/050/1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/images/050/2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/images/050/3.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/images/050/4.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit bb179cf

Please sign in to comment.