• 附录B:有趣的代码片段
    • 自重写程序
    • 三元表达式
    • 禁止 main 函数退出的方法
    • 基于管道的随机数生成器
    • Assert测试断言

    附录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. }