附录B:有趣的代码片段

这里收集一些比较有意思的Go程序片段。

自重写程序

UNIX/Go语言之父 Ken Thompson 在1983年的图灵奖演讲 Reflections on Trusting Trust 就给出了一个C语言的自重写程序。

最短的C语言自重写程序是 Vlad Taeerov 和 Rashit Fakhreyev 的版本:

  1. main(a){printf(a="main(a){printf(a=%c%s%c,34,a,34);}",34,a,34);}

下面的Go语言版本自重写程序是 rsc 提供的:

  1. /* Go quine */
  2. package main
  3. import "fmt"
  4. func main() {
  5. fmt.Printf("%s%c%s%c\n", q, 0x60, q, 0x60)
  6. }
  7. var q = `/* Go quine */
  8. package main
  9. import "fmt"
  10. func main() {
  11. fmt.Printf("%s%c%s%c\n", q, 0x60, q, 0x60)
  12. }
  13. var q = `

在 golang-nuts 中还有很多版本:

  1. package main;func main(){c:="package main;func main(){c:=%q;print(c,c)}";print(c,c)}
  1. package main;func main(){print(c+"\x60"+c+"\x60")};var c=`package main;func main(){print(c+"\x60"+c+"\x60")};var c=`

如果有更短的版本欢迎告诉我们。

三元表达式

  1. func If(condition bool, trueVal, falseVal interface{}) interface{} {
  2. if condition {
  3. return trueVal
  4. }
  5. return falseVal
  6. }
  7. a, b := 2, 3
  8. max := If(a > b, a, b).(int)
  9. println(max)

禁止 main 函数退出的方法

  1. func main() {
  2. defer func() { for {} }()
  3. }
  4. func main() {
  5. defer func() { select {} }()
  6. }
  7. func main() {
  8. defer func() { <-make(chan bool) }()
  9. }

基于管道的随机数生成器

随机数的一个特点是不好预测。如果一个随机数的输出是可以简单预测的,那么一般会称为伪随机数。

  1. func main() {
  2. for i := range random(100) {
  3. fmt.Println(i)
  4. }
  5. }
  6. func random(n int) <-chan int {
  7. c := make(chan int)
  8. go func() {
  9. defer close(c)
  10. for i := 0; i < n; i++ {
  11. select {
  12. case c <- 0:
  13. case c <- 1:
  14. }
  15. }
  16. }()
  17. return c
  18. }

基于select语言特性构造的随机数生成器。

Assert测试断言

  1. type testing_TBHelper interface {
  2. Helper()
  3. }
  4. func Assert(tb testing.TB, condition bool, args ...interface{}) {
  5. if x, ok := tb.(testing_TBHelper); ok {
  6. x.Helper() // Go1.9+
  7. }
  8. if !condition {
  9. if msg := fmt.Sprint(args...); msg != "" {
  10. tb.Fatalf("Assert failed, %s", msg)
  11. } else {
  12. tb.Fatalf("Assert failed")
  13. }
  14. }
  15. }
  16. func Assertf(tb testing.TB, condition bool, format string, a ...interface{}) {
  17. if x, ok := tb.(testing_TBHelper); ok {
  18. x.Helper() // Go1.9+
  19. }
  20. if !condition {
  21. if msg := fmt.Sprintf(format, a...); msg != "" {
  22. tb.Fatalf("Assertf failed, %s", msg)
  23. } else {
  24. tb.Fatalf("Assertf failed")
  25. }
  26. }
  27. }
  28. func AssertFunc(tb testing.TB, fn func() error) {
  29. if x, ok := tb.(testing_TBHelper); ok {
  30. x.Helper() // Go1.9+
  31. }
  32. if err := fn(); err != nil {
  33. tb.Fatalf("AssertFunc failed, %v", err)
  34. }
  35. }